Python初学者制作俄罗斯方块小游戏之路

适合初学者超详细Python制作俄罗斯方块教程

  • 背景
  • 实现过程
    • 绘制窗口
    • 添加控件与文本
    • 添加画布
    • 绘制一小方块
    • 俄罗斯方块定义
    • 游戏开始前的初始化
    • 功能模块设计
      • 计算分数
      • 显示下一个方块
      • 联合
      • 画出方块组合(俄罗斯方块)
      • 下降
      • 可移动判断
      • 消行
      • 闪烁
      • 旋转
      • 加速
      • 左右移动
      • 直接下落
      • 按钮功能
    • 按键交互
    • 添加背景图
  • 成果展示

背景

我刚学Python三天,但不想一直看书,于是在网上学习了一些用Python制作俄罗斯方块的代码,有的代码没有注释,并且比较难理解,这里我找到了一个博主的代码,思路很清晰,游戏运行后也很顺畅,但代码没有注释,所以我就自己拿来学习并做了一定的修改。为了方便和我一样想拿小游戏练习巩固基础知识的小伙伴,我将自己的学习收获分享给大家,希望大家学习代码中能快速理解!

实现过程

过程主要分为以下几部分:

  1. 窗口设计
  2. 画布设计
  3. 方块定义与设置
  4. 方块功能方法设计
  5. 控件功能方法设计
    大致过程就分为这几部分,具体的流程见下面详细分析,原理啥的都会放在具体的部分中讲解

绘制窗口

在Python中,我们可以用tkinter模块进行窗口设计。为了使用此模块,我们首先需要import它:

from tkinter import *
import time
import random
import math
from tkinter import messagebox
from PIL import ImageTk, Image

在这里,我一下子把所有要导入的库块全贴出来了,下面对其解释:
from tkinter import * :导入tkinter库中所有的类、变量、函数等信息。
import time : 导入时间库(因为在代码中用到了sleep函数)
import random :导入随机数生成库
from tkinter import messagebox : 导入messagebox弹窗库
from PIL import ImageTk, Image :从PIL导入ImageTk、Image库,用于添加背景图片
前四个都是Python自带的库,不需要我们自己安装,但是最后一个需要我们安装PIL库(PIL是Python处理图像的库),安装方法在这里也给出:
(1)找到pip.exe所在的文件夹,我的是在D:\Python37\Scripts (一般pip.exe都在Python安装目录中Scripts文件夹里)
在这里插入图片描述
(2)运行cmd,将路径跳转到pip.exe所在的文件夹(我的是Scripts),输入pip install pillow , 电脑将会自动搜索pillow并进行安装,安装成功将会看到Successfully字样:
在这里插入图片描述
此时,Pillow就安装成功了。
之后,我们进行窗口绘制,代码如下:

        self.win = Tk()                                   #创建窗口self.win.title("俄罗斯方块_by ZSQ")  self.win.geometry('450x610+400+100')  #self.win.geometry('w×h+x+y'),w:窗口宽度,h:窗口长度,x,y是窗口在屏幕上的位置self.win.resizable(0, 0)                         #窗口的长宽不可改变self.win.mainloop()                              #让窗口运行起来

这样我们一个制作了一个窗口,效果如下:
在这里插入图片描述

添加控件与文本

下面我们添加四个按钮,分别是开始、暂停、重新开始、退出。多个文本,比如:等级、分数,对应代码如下:

        self.pauseBut = Button(self.win, text="暂停", bg='#7B8E9C', height=1, width=10, font=(10), command=self.pause)self.pauseBut.place(x=338, y=473)self.startBut = Button(self.win, text="开始",bg = '#DEC8B0', height=1, width=10, font=(10), command=self.startgame)self.startBut.place(x=338, y=430)self.restartBut = Button(self.win, text="重新开始",bg = '#EBB78C',height=1, width=10, font=(10), command=self.restart)self.restartBut.place(x=338, y=516)self.quitBut = Button(self.win, text="退出", height=1,bg = '#CA4F53' ,width=10, font=(10), command=self.quitgame) self.quitBut.place(x=338, y=559)self.lab_score = Label(self.win, text="分数:0", font=("宋体",16,"normal"))self.lab_score.place(x=335, y=50)self.lab_scoreEx = Label(self.win, text = "每200升级一次", font = ("宋体",8,"normal"))self.lab_scoreEx.place(x=335,y=80)self.lab_grade = Label(self.win, text="等级:1", font=("宋体",16,"normal"))self.lab_grade.place(x=335, y=115)self.lab_next = Label(self.win, text = "下一个:",font=("宋体",16,"normal"))self.lab_next.place(x=335,y=180)

这里Button、Label都是控件,括号里是设置他们的参数,不懂的小伙伴可以自行百度(其实很好理解的),其中四个Button中的command是触发,即点击了按钮就触发相应方法(后面讲述)。添加控件后的效果如下:
在这里插入图片描述

添加画布

绘制好窗口,我们利用Canvas组件添加画布,我们这里添加两个画布,分别是下落画布(huabu)和下一块显示画布(huabu_right),对应代码如下:

        self.huabu = Canvas(self.win ,bg ='#DEF6FF' ,height=600, width=COLUMN * (BIANCHANG+1), takefocus=True) #方块下落画布self.huabu.place(x=2, y=2) #画布的位置self.huabu_right = Canvas(self.win,bg = '#DEF6FF',height=100, width=100) #下一个方块预览画布self.huabu_right.place(x=335,y=210)

因为其中涉及到了一些变量的使用(例如COLUMN, BIANCHANG等),这些都是事先声明好的全局变量,在这里贴出声明代码:

		BIANCHANG = 19        #一小方块边长COLOR = ['red', 'orange', 'yellow', 'green', 'blue', 'purple', '#00C5CD', '#00EE76', '#388E8E', '#556B2F', '#6B8E23','#8B2252', '#8B6969', '#A0522D', '#BC8F8F', '#BC8F3F', 'black']      #颜色COLUMN = 16           #列数ROW = 30              #行数imgpath = 'menglong_.gif'  #背景图片			img = Image.open(imgpath)  #获取背景图片

回到画布上,刚刚添加完画布后,整体效果如下:
在这里插入图片描述
至此,窗口、画布的添加到此完毕,其中细节我没有过多讲解(比如Canvas里的参数含义,这些都可以自行搜索,讲的都很详细),接下来就是设计方块以及实现各种功能。

绘制一小方块

我们定义一个类(fangk)来在画布上具体位置上画一小块,代码如下:

class fangk: def __init__(self, huabu, col, row):  #属于对象的数据成员, #self参数必须是第一个形参,它代表对象本身,在类的实例方法中访问实例属性时,需要以self为前缀self.huabu = huabu  self.col, self.row = col, row    #col-->第几行的行,row-->第几列的列self.color = COLOR[self.row % 16] #方块颜色self.havafk = False               #界面上有无方块的标志def setvisible(self, statu):  #设置显示与否if statu > 0:x = self.col * (BIANCHANG+1)     y = 582 - (ROW - self.row - 1) * (BIANCHANG + 1)  self.fk = self.huabu.create_rectangle(x, y, x + BIANCHANG, y + BIANCHANG, fill = self.color) #画块#(creat_rectangle(x1,y1,x2,y2):画一个矩形(对角顶点坐标为(x1,y1),(x2,y2))self.line1 = self.huabu.create_line(x, y, x, y + BIANCHANG, fill = 'white') #边线加白#create_line() :画线self.line2 = self.huabu.create_line(x, y, x + BIANCHANG, y, fill = 'white')self.havefk = Trueelif statu ==0 and self.havefk:  self.huabu.delete(self.fk)#detele()删除对变量的引用self.huabu.delete(self.line2)self.huabu.delete(self.line1)self.havefk = Falseelse: return -1def set_color(self, color):       #设置颜色self.color = colorreturn self

这段代码的作用是在画布上第row行,第col列绘制一个方块,并设置其颜色,再通过setvisible方法设置是否可见。即:
在这里插入图片描述
在这段代码中,因为y轴正方向与行数增加顺序是相反的,行数所对应的y值为582 - (ROW - self.row - 1) * (BIANCHANG + 1) ,
之后,我们在elsfk类中遍历整个画布,就能画出所有方块,只需要一行代码:

        self.fangkuai_map = [ [fangk(self.huabu, i, j) for i in range(COLUMN)] for j in range(ROW) ]  

俄罗斯方块定义

我们知道,俄罗斯方块一共有19种,每个都是由四个小方块组成,我们选其中一小块当参考(我们叫它原块,坐标为(0,0)),如下所示:
在这里插入图片描述
我们用一个列表(fk_type)存储每个类型的方块,代码如下:

def __init__(self):self.fk_type = [[(0, 0, 1, 1), (0, 1, 0, 1)],     # 正方形 [(0, 0, 0, 0), (1, 0, -1, -2)],   # 长条 [(-1, 0, 1, 2), (0, 0, 0, 0)],    #      [(0, 1, 0, -1), (0, 1, 1, 0)],    # S    [(0, -1, -1, 0), (0, 1, 0, -1)],     [(0, -1, 0, 1), (0, 1, 1, 0)],    # Z   [(0, 1, 1, 0), (0, 1, 0, -1)],         [(0, 0, -1, 1), (0, 1, 0, 0)],    # T型   [(0, 0, 0, 1), (0, 1, -1, 0)],[(0, 1, 0, -1), (0, 0, -1, 0)],[(0, 0, -1, 0), (0, 1, 0, -1)],[(0, 1, 1, -1), (0, -1, 0, 0)],    # J [(0, 1, 0, 0), (0, 1, 1, -1)],[(0, -1, -1, 1), (0, 1, 0, 0)],[(0, 0, 0, -1), (0, 1, -1, -1)],[(0, 1, 1, -1), (0, 1, 0, 0)],     # L [(0, -1, 0, 0), (0, 1, 1, -1)],[(0, -1, -1, 1), (0, -1, 0, 0)],[(0, 0, 0, 1), (0, 1, -1, -1)]]

其中[(),()]第一个括号里是横坐标,第二个括号里是对应的纵坐标。

游戏开始前的初始化

初始化的作用是在游戏开始前对一些变量和窗口的控件属性进行初始赋值操作,并且生成下一个物块。
代码:

    def initgame(self):self.map = [[0] * COLUMN for _ in range(ROW)]        #初始化画布self.map_before = [[0] * COLUMN for _ in range(ROW)] self.base_map = [[0] * COLUMN for _ in range(ROW)]   self.color_map = [[0] * COLUMN for _ in range(ROW)]  self.score = 0 #分数self.grade = 1 #等级#self.speed = 20 #速度self.next_fangk_type = random.randrange(0, 19) #下一个方块类型self.next_color = random.randrange(0, 17) #下一个方块的颜色self.lab_score.config(text ="分数:0")self.lab_grade.config(text = "等级:1")self.lab_next.config(text = "下一个:")self.lab_scoreEx.config(text = "说明:每200升级一次")self.lock_operation = False #锁,类似于生产者消费者问题中的锁self.last_row = 1  #上次消除的行数#self.sum_row = 0   #总共消除的行数self.interval = 0  #下降间隔

map是一个列表,存储的是每一行有无物块的标志,1代表有物块,0则代表没有物块:
在这里插入图片描述
map_before:存储前一个map数据
base_map: 底层(基础)数据,比如某个方块移动时其他的map数据
color_map: 颜色数据,每一个地方放的不再是0或1 ,而是具体的颜色16进制值

功能模块设计

讲解都放在了注释上面,大家看我的注释即可。

计算分数

    def cal_score(self, row): #row -->此次消除的行数'''计算分数'''self.score = self.score + [row * 10 , int(row * 10 * (1 + row/10))][self.last_row < row] #这次消除行数比上次的多即可得到加成#[a,b][c]-->c成立选b,c不成立选aself.lab_score.config(text="分数:" + str(self.score))self.last_row = row #self.sum_row += row        self.grade = self.score //200 +1 #分数每升高200增加一级self.lab_grade.config(text = "等级:" + str(self.grade))

计算分数采用激励机制,此次消除行数大于上次,可以得到额外加分。

显示下一个方块

    def next_fk(self):'''显示下一个方块'''self.cur_color = self.next_colorself.cur_fk_type = self.next_fangk_typeself.next_color = random.randrange(0, 17)self.next_fangk_type = random.randrange(0, 19)for i in self.huabu_right.find_all():     #清空上次显示画布self.huabu_right.delete(i)for i in range(4):fangk(self.huabu_right, 2 + self.fk_type[self.next_fangk_type][0][i], #列2 - self.fk_type[self.next_fangk_type][1][i]).set_color(COLOR[self.next_color]).setvisible(1)#       位置                                                          颜色                进行显示 #y轴正方向与行数增加方向相反self.cur_fk = self.fk_type[self.cur_fk_type]self.cur_location = [{'x': 7, 'y':1},{'x': 7, 'y': 0}][self.cur_fk_type in (2, 11, 17)] #根据当前物块类型选择初始坐标, x对应列数,y对应行数self.combind()  self.draw_map() if not self.test_map():    afterFail = messagebox.askquestion("失败", "游戏失败,点击\"是\"重新开始,否则退出游戏") #返回yes或noif afterFail == 'yes':self.lock_operation = True  self.restart()else:self.win.destroy()

联合

    def combind(self):'''组合,坐标与行列之间的映射,确定显示方块的位置与颜色 '''self.map = [a[:] for a in self.base_map]      for i in range(len(self.cur_fk[1])):     #坐标和行列之间的映射x = self.cur_location['x'] + self.cur_fk[0][i]y = self.cur_location['y'] - self.cur_fk[1][i]self.map[y][x] = 1   #y高度对应行数,x对应列数,map画布就是起到决定那些位置显示方块self.color_map[y][x] = self.cur_color        #对应位置设置当前颜色

画出方块组合(俄罗斯方块)

    def draw_map(self):'''画出刚出来的俄罗斯方块'''for i in range(ROW):for j in range(COLUMN):if self.map[i][j] != self.map_before[i][j]:self.fangkuai_map[i][j].set_color(COLOR[self.color_map[i][j]]).setvisible(self.map[i][j])#把所有方块画布上的方块全设成一个颜色,但是只有map画布上为1的才显示self.map_before = [i[:] for i in self.map]   #保存当前的显示情况self.win.update()  #窗口更新

下降

    def drop(self):'''物块下降'''self.cur_location['y'] += 1 #纵坐标增大if self.cur_location['y'] - min(self.cur_fk[1]) < ROW and self.test_map(): #没有顶部并且可以下落self.combind()self.draw_map()return Trueelse:self.cur_location['y'] -= 1 #判断不能下降后,纵坐标-1self.base_map = [i[:] for i in self.map]self.delete_row()       #判断是否可以消行self.draw_map()        self.next_fk()return False 

可移动判断

    def test_map(self):'''可移动判断'''for i in range(len(self.cur_fk[0])):x = self.cur_location['x'] + self.cur_fk[0][i]y = self.cur_location['y'] - self.cur_fk[1][i] #这里self.cur_location['y'],self.cur_location['x'] 会提前加减(为了判断)if self.base_map[y][x] > 0: return False # >0说明此位置有物块,不可移动return True

消行

    def delete_row(self):'''删行'''del_row = []for i in range(max(self.cur_fk[1]) - min(self.cur_fk[1]) + 1): #求遍历的行数if self.base_map[self.cur_location['y'] - min(self.cur_fk[1]) - i ] == [1] * COLUMN: #判断所一物块下落完后的行是否全为1del_row.append(self.cur_location['y'] - min(self.cur_fk[1]) - i) #存储要删除的行(第几行)if not del_row == []: #del_row不为空说明有行要删除self.flash(del_row) #闪烁要删的行self.base_map = [r for r in self.base_map if not r == [1] * COLUMN] #把不是全1的行抽出来(相当于删行)self.base_map = ([[0] * COLUMN ] * (30 - len(self.base_map))) + self.base_map #填0行#每消一行,相当于顶部多一行全0, 所以必须是[0,0,0,...0] + self.base_mapself.cal_score(len(del_row)) #计算分数

闪烁

    def flash(self, del_rows):'''闪烁消除的行'''self.lock_operation = Truefor times in range(6): #闪烁次数for j in del_rows: for i in self.fangkuai_map[j]: #fangkuai_map[j] ---> 取出第j行i.setvisible(int(0.5 + times % 2 *0.5))  #闪烁效果, times为偶数,int(0)=0,times为奇数,int(1)=1self.win.update()time.sleep(0.2)   #设置闪烁间隔(其实就是刷新间隔)self.lock_operation = False

旋转

    def rotate(self, event):'''旋转'''if not self.lock_operation:if not self.cur_fk_type ==0 :temp = self.cur_fk_typeself.cur_fk_type = [(self.cur_fk_type - 7) // 4 * 4 + self.cur_fk_type % 4 + 7,(self.cur_fk_type - 1) // 2 * 2 + self.cur_fk_type % 2 + 1][self.cur_fk_type in range(1,7)]#长条(1,2)、Z(3,4)、S型(5,6)方块变换都只有一种,变换的公式为# 变换后的类型序号 = (当前序号-1)//2 * 2 + 当前序号 % 2 + 1 # 1-->2, 2-->1; 3-->4, 4-->3; 5-->6, 6-->5#L, J, T型的变换公式:变换后的类型序号 = (当前序号-7)//4 * 4 + 当前序号 % 4 + 7# T型:10-->9-->8-->7-->10self.cur_fk = self.fk_type[self.cur_fk_type]if self.cur_location['x'] + min(self.cur_fk[0]) + 1 <= 0 or self.cur_location['x'] + max(self.cur_fk[0]) >= COLUMN or not self.test_map() or self.cur_location['y'] + min(self.cur_fk[1]) + 1 <= 0:  #看旋转后是否出界,出界则不旋转print('can\'t rotate')self.cur_fk_type = temp #还原self.cur_fk = self.fk_type[self.cur_fk_type]#四种情况不能旋转:# 旋转后会出左边界 ---> self.cur_location['x'] + min(self.cur_fk[0]) + 1 <= 0 # 旋转后会出右边界 ---> self.cur_location['x'] + max(self.cur_fk[0]) >= COLUMN# 直接旋转会和已有的物块重合 ---> self.test_map()# 旋转后会出上边界 ---> self.cur_location['y'] + min(self.cur_fk[1]) + 1 < 0self.combind()self.draw_map()                              

加速

    def quick_drop(self, event):if not self.lock_operation: #没有上锁,可按键self.drop()

左右移动

    def move_left(self, event):if not self.lock_operation:self.cur_location['x'] -= 1if self.cur_location['x'] + min(self.cur_fk[0]) + 1 > 0 and self.test_map():   #判断是否可以左移,以及左移后是否出了左边界self.combind()self.draw_map()else:self.cur_location['x'] += 1def move_right(self, event):if not self.lock_operation:self.cur_location['x'] += 1if self.cur_location['x'] + max(self.cur_fk[0]) < COLUMN and self.test_map():  #判断是否可以右移,以及右移后是否出了右边界self.combind()self.draw_map()else:self.cur_location['x'] -= 1

直接下落

    def down_straight(self, event):while not self.lock_operation and self.drop(): pass   #利用循环让它自动下落,因为循环时间极短,所以人眼看的就有直接到底的感觉

按钮功能

    def pause(self):messagebox.showinfo("暂停", "游戏暂停中,点击确认返回游戏")def restart(self):for i in self.huabu.find_all():   self.huabu.delete(i)             self.initgame()   #重新开始后需要初始photo = ImageTk.PhotoImage(img)  #重新加载背景图片self.huabu.create_image(160,305,image = photo)self.startgame()  #初始完毕后开始游戏def quitgame(self):isQuit = messagebox.askquestion('退出', "确定要退出吗?")if isQuit == 'yes': self.win.destroy()  #用quit()方法开始后退不出去def startgame(self):self.startBut.config(state = DISABLED) #点击完开始按钮后不可再点击self.next_fk()  #下一俄罗斯方块 while not self.lock_operation:  time.sleep(0.05)       if self.interval == 0:  self.drop()self.interval = (self.interval + 1) % (22 - self.grade *4)   #每隔一段时间自动掉落self.win.update()  #刷新窗口界面

按键交互

按键交互模块也比较简单,设置固定按键对应方法即可。

        self.huabu.bind_all('<KeyPress-a>', self.move_left)   #字母(例如A键是KeyPress-a而不能写成Keypress-A)必须小写self.huabu.bind_all('<KeyPress-d>', self.move_right)self.huabu.bind_all('<KeyPress-s>', self.quick_drop)self.huabu.bind_all('<KeyPress-w>', self.rotate)self.huabu.bind_all('<Left>', self.move_left)self.huabu.bind_all('<Right>', self.move_right)self.huabu.bind_all('<Down>', self.quick_drop)self.huabu.bind_all('<Up>', self.rotate)self.huabu.bind_all('<KeyPress-space>', self.down_straight)

添加背景图

为了美观,我们可以给画布添加背景图,因为在之前定义全局变量时已经引入了图片,所以我们只需在elsfk类__init__方法中加入如下代码:

        photo = ImageTk.PhotoImage(img)self.huabu.create_image(160,302,image = photo)

成果展示

在这里插入图片描述
至此我们的整个俄罗斯方块的设计就算完成了,希望我的教程能够帮助大家快速理解学习。如果大家想下载全部代码,可以进入我的资源进行下载。但是我希望大家能自己敲一遍吖,锻炼自己的思考与逻辑能力!

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://xiahunao.cn/news/1380358.html

如若内容造成侵权/违法违规/事实不符,请联系瞎胡闹网进行投诉反馈,一经查实,立即删除!

相关文章

python可以制作游戏脚本吗_如何用python制作游戏脚本?

对于游戏编程来说,使用脚本语言可以快速地开发游戏逻辑,节省开发新型自定义语言的时间和开销,并且脚本语言通常要比编程者创造的语言更加的强大。小伙伴们学习python有一段时间了,有没有发现python语言的很强大和简洁,并且很容易嵌入,是一个不错的脚本语言呢?今天我们就…

用Html5制作 汤姆猫 小游戏

以下汤姆猫是用html5制作的小游戏&#xff1b; 建议火狐测试&#xff0c;然后把火狐调成 响应式设计模式&#xff08;以便模拟手机屏幕&#xff09;&#xff0c;设置--->开发者--->响应式设计模式&#xff1b; 如下图 以下是html文件&#xff1a; <!DOCTYPE htm…

Fairy下载和使用

写在最前&#xff1a;本系列中将会涉及到 Unity&#xff0c;C#&#xff0c;Lua和FairyGUI&#xff08;FGUI&#xff09;。 FairyGUI介绍 官网&#xff1a; FairyGUI 编辑器下载&#xff1a; FairyGUI 截至文档记录最新版&#xff1a; https://res.fairygui.com/FairyGUI-Ed…

小游戏开发引擎CocosCreator

小游戏 六彩跳棋 已经通过审核并且发布了好几天了&#xff0c;对跳棋感兴趣的朋友可以去看看&#xff0c;在微信游戏里搜索 六彩跳棋 &#xff0c;点击 立即玩 吧&#xff01;进去游戏后&#xff0c;需要点击 获取头像昵称 才能得到玩家数据&#xff0c;然后 划动屏幕 选择游戏…

制作打怪小游戏Kill Bill

使用construct2制作游戏Kill Bill construct2适合新手小菜鸟&#xff08;比如我&#xff09;进行游戏制作&#xff0c;以下的游戏Kill Bill就是由它制成。 制作步骤如下。 寻找素材&#xff0c;新建工程并插入对象对游戏对象添加行为构建事件以完成对游戏规则的设置完善细节 寻…

第二个Flash小游戏制作(打飞机)

帧一的动作 import flash.events.MouseEvent;import flash.events.Event; stop(); btn.addEventListener(MouseEvent.CLICK, btn_click); function btn_click(event:Event):void{ gotoAndStop("fire"); } 帧二的动作 atartPlaneAir(); package{ import fla…

flash游戏和HTML5游戏,Flash动画和H5小游戏哪个更好?

原标题&#xff1a;Flash动画和H5小游戏哪个更好&#xff1f; 大家都知道现在H5小游戏很火&#xff0c;但是flash动画也有其历史渊源和优势。下面本文就重点带大家看看flash动画和H5小游戏哪个更好。 1、制造本钱上看&#xff0c;flash动画如同比较复杂一点的H5动画的价格差不多…

第一个Flash小游戏制作(1)

目标&#xff1a;是制作一个类似连连看的游戏&#xff08;如下图&#xff09;。 素材可以在附件中下载&#xff0c;包括&#xff1a; 1.图片的MovieClip 2.两个自定义按钮&#xff08;也可以使用自己的按钮&#xff09; 3.一些声音文件 第一步&#xff1a; 我们先新建一个(…

制作flash cs的简单小游戏

以flash cs6为例制作小游戏。 文件素材可以从图片上截图下来之后&#xff0c;稍微用ps处理下就行了。 需要的有&#xff1a; 1.一个背景板。2.气球。3.齿轮。 新建一个Game.as文件。把下面代码放进去。 package{ import flash.display.MovieClip; import flash.events.Event; i…

AIStudio扫描王实现与原理详解

★★★ 本文源自AI Studio社区精品项目&#xff0c;【点击此处】查看更多精品内容 >>> AIStudio扫描王实现与原理详解 一、前言 大家经常有需要使用扫描件的时候&#xff0c;如果是要求不太高的场景&#xff0c;我们通常会使用手机拍照&#xff0c;再经过一些APP应用…

基于 requests 的全能扫描王爬虫实践

投稿人&#xff1a;Alan 摘要&#xff1a;全能扫描王是文件扫描留档的重要工具&#xff0c;本文利用requests爬虫将手机客户端的扫描文件&#xff0c;同步至电脑端。 一、背景 在审计工作中&#xff0c;需要大批量扫描文件留档&#xff0c;全能扫描王成为主流的手机端扫描工具。…

【OpenCV】基于Qt的“破产版”全能扫描王

功能介绍 图片打开和保存图片矫正&#xff08;证件扫描、文字纠正…&#xff09;图片锐化增强图片清空阈值设置 项目实现 基本思路&#xff08;证件扫描&#xff09; 抠图&#xff1a;提取轮廓矫正&#xff1a;透视变换锐化增强&#xff1a;二值化 算法设计&#xff08;证…

eNSP:ibgp的破水平切割练习

实验要求&#xff1a; 拓扑展示&#xff1a; 命令操作&#xff1a; R1&#xff1a; <Huawei>sys [Huawei]sys r1 [r1]int g 0/0/1 [r1-GigabitEthernet0/0/1]ip add 12.1.1.1 24 [r1-GigabitEthernet0/0/1]int lo0 [r1-LoopBack0]ip add 1.1.1.1 24 [r1-LoopBack0]osp…

css clip-path 画五角星

简介 使用裁剪方式创建元素的可显示区域&#xff0c;实现区域裁剪。 浏览器兼容性 常用的三种方法 1. clip-path: circle(50px at 50px 50px) 以 50px 50px 的坐标为圆心裁剪一个半径 50px 的圆&#xff1b; 2. clip-path: ellipse(30px 40px at 50px 50px) 以 50px 50px…

canvas绘图详解-06-绘制一个五角星-常用绘图原理

先讲如何画一个正规的五角星 在五角星的内外画两个圆&#xff0c;五角星有五个角&#xff0c;360/572度 所以得出这两个角的度数 然后算出这两个点坐标 角度转弧度 角度/180*Math.PI 所以外顶点坐标 x: Math.cos( (1872*i)/180*Math.PI) * R y: Math.sin((1872*i)/180*Math.P…

钓鱼网站原理实验

实验环境:一台Windows 2003&#xff08;WA&#xff09;作为客户机&#xff0c;一台Linux&#xff08;LB&#xff09;作为服务器。 1.LB设置网络适配器 2.LB配置eth0&#xff08;vim /etc/sysconfig/network-scripts/ifcfg-eth0&#xff09; 3.LB将eth0的内容copy一份到eth1 …

电子邮件如何追溯到他们的源IP地址

你要做的第一件事当你听到检查发送电子邮件通知,对吧? 这是最快的方法找出谁是电子邮件,以及可能的内容。 但是你知道每个邮件都有更多的信息比出现在大多数的电子邮件客户端? 有主机的信息发送者包括在邮件头信息可以用来跟踪电子邮件回源。 下面是如何跟踪,邮件回它是从哪…

红队攻击:轻松玩转邮件钓鱼

首发在合天智汇&#xff1a;https://mp.weixin.qq.com/s/sRXnwIdy3eQ0CJS58_bI1g 邮件钓鱼老生常谈&#xff0c;攻击手段也并不新颖。但对于网络安全工程师来说,“懂原理”和“会使用”是两个概念。会用&#xff0c;用得好不好&#xff0c;又是不同的层次。红队攻击要讲究攻击的…

seeker+ngrok 钓鱼获取目标位置

免责说明&#xff1a;本文章只是参考&#xff0c;一切后果自行承担&#xff0c;网络环境靠大家&#xff0c;遵守网络安全法是每个人应尽的责任 文章目录 一、工具介绍seekerngrok 二、使用步骤 一、工具介绍 seeker seeker工具是一款社会工程学的利器&#xff0c;可以通过see…

使用十六进制IP地址的网络钓鱼攻击活动

网络犯罪分子正在不断优化其网络攻击工具&#xff0c;策略和技术&#xff0c;以逃避垃圾邮件检测系统。 由于一些系统会直接提取邮件中内嵌的链接进行检测&#xff0c;而一种此类URL混淆技术采用了URL主机名部分中使用的编码十六进制IP地址格式来逃避检测。 由于IP地址可以用多…