-
Notifications
You must be signed in to change notification settings - Fork 10
/
jumpMan.py
255 lines (216 loc) · 8.02 KB
/
jumpMan.py
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
# -*- coding: utf-8 -*-
"""
Created on Mon May 28 20:21:27 2018
@author: Administrator
"""
import numpy as np
from MyLibrary import *
FPS=120
screenwidth=288
screenheight=512
fontsize=30
player_filename="players.png"
player_frame_width=48
player_frame_height=48
player_frame_num=4
base_filename="base.png"
base_frame_width=80
base_frame_height=15
base_frame_num=1
base_velocity_y=np.arange(-3,-8,-0.5)
stage=0
level=0
maxlevel=len(base_velocity_y)-1
timer_tick=30
interval=90
player_velocity_y=6
final_color=0,0,0
game_over=False
player_moving=False
FPSclock=pygame.time.Clock()
#创建玩家、平板的精灵组
player_group=pygame.sprite.Group()
base_group=pygame.sprite.Group()
#在屏幕下方随机位置生成板
def getRandomBase(filename,framewidth,frameheight,frameamount,velocity_y=-3,distance=100):
base=MySprite()
base.load(filename,framewidth,frameheight,frameamount)
base.position=random.randint(0,screenwidth-base.frame_width),distance+screenheight
base.velocity.y=velocity_y
base_group.add(base)
#当有板超出屏幕上方时,改变其Y坐标至屏幕下方
def chBase():
global stage
for base in base_group:
if base.Y<-base.frame_height:
stage+=1
base.Y=screenheight+interval
base.X=random.randint(0,screenwidth-base.frame_width)
#计算游戏难度、板的速度
def calcLevel():
global level
old_level=level
present_level=stage//20
if present_level>=old_level and level<maxlevel:
level+=1
return base_velocity_y[level]
#计算玩家的速度
def calcVelocity(direction,vel=1.0):
velocity=Point(0,0)
if direction==0:#not move
velocity.x=0
elif direction==1:#to the left
velocity.x=-vel
elif direction==2:#to the right
velocity.x=vel
return velocity
#当玩家按左右键时更改帧的图像
def frameChange():
if player.direction==0:#不动
player.first_frame=3
player.last_frame=3
elif player.direction==1:#向左
player.first_frame=0
player.last_frame=0
elif player.direction==2:#向右
player.first_frame=2
player.last_frame=2
if player.frame<player.first_frame:
player.frame=player.first_frame
#获取每个像素的透明度矩阵
def getHitmasks(image):
mask = []
for x in range(image.get_width()):
mask.append([])
for y in range(image.get_height()):
mask[x].append(bool(image.get_at((x,y))[3]))
return mask
#如果碰撞,则返回True
def checkCrash(player,base,hitmasks):
#碰到底部
if player.Y + player.frame_height >= screenheight - 1:
return True
else:
player_rect = pygame.Rect(player.X, player.Y, player.frame_width, player.frame_height)
for base in base_group:
base_rect = pygame.Rect(base.X, base.Y, base.frame_width, base.frame_height)
player_hit_mask = hitmasks['player']
base_hit_mask = hitmasks['base']
#检测是否有像素碰撞
collide = pixelCollision(player_rect, base_rect, player_hit_mask, base_hit_mask)
if collide:
return True
return False
#检测像素是否碰撞
def pixelCollision(rect1, rect2, hitmask1, hitmask2):
rect = rect1.clip(rect2)
if rect.width == 0 or rect.height == 0:
return False
x1, y1 = rect.x - rect1.x, rect.y - rect1.y
x2, y2 = rect.x - rect2.x, rect.y - rect2.y
for x in range(rect.width):
for y in range(rect.height):
if hitmask1[x1+x][y1+y] and hitmask2[x2+x][y2+y]:
return True
return False
class Game():
def __init__(self,screen0):
global screen, timer, player, font,player_group,base_group
pygame.init()
player_group = pygame.sprite.Group()
base_group = pygame.sprite.Group()
screen = screen0
timer = pygame.time.Clock()
player = MySprite()
player.load(player_filename, player_frame_width, player_frame_height, player_frame_num)
player.position = screenwidth // 3, screenheight // 3
player_group.add(player)
self.reset_score = True # 该标志用于确保score的重置在下一帧才进行
for i in np.arange(0, 501, 100):
getRandomBase(base_filename, base_frame_width, base_frame_height, base_frame_num, base_velocity_y[0], i)
def frameStep(self,input_actions):
if self.reset_score:
self.score=0
self.reset_score=False
pygame.event.pump()
reward=0.2
self.score+=1
terminal=False
timer.tick(timer_tick)
ticks = pygame.time.get_ticks()
for event in pygame.event.get():
if event.type == QUIT:
pygame.quit()
sys.exit()
keys = pygame.key.get_pressed()
if keys[K_ESCAPE]:
pygame.quit()
sys.exit()
if(input_actions[0]==1):
player_moving = True
player.direction = 1
elif input_actions[2]==1:
player_moving = True
player.direction = 2
else:
player.direction = 0
global game_over,level
if game_over:
reward=-5
level = 0
terminal=True
global screen
self.__init__(screen)
game_over=False
else:
if player.direction:
player.velocity = calcVelocity(player.direction, 5)
#改变帧图像
frameChange()
#更新图像
player_group.update(ticks, 50)
#检测碰撞,以确定速度
player_moving = True
for base in base_group:
# player={}
Hitmasks = {}
Hitmasks['base'] = (getHitmasks(base.image))
Hitmasks['player'] = (getHitmasks(player.image))
iscrash = checkCrash(player, base,Hitmasks)
if iscrash:
if player.Y + player.frame_height >= base.Y and player.Y < base.Y:
if player.Y + player.frame_height < base.Y + 15:
player.Y = base.Y - player.frame_height + 2
player.velocity.y = base.velocity.y
elif player.X + player.frame_width >= base.X and player.X < base.X:
player.X = base.X - player.frame_width
player.velocity.y = player_velocity_y
elif player.X <= base.X + base.frame_width and base.X < player.X:
player.X = base.X + base.frame_width
player.velocity.y = player_velocity_y
break
else:
player.velocity.y = player_velocity_y
if player_moving:
player.X += player.velocity.x
player.Y += player.velocity.y
if player.X < 0:
player.X = 0
elif player.X > screenwidth - player.frame_width:
player.X = screenwidth - player.frame_width
if player.Y < 0 or player.Y > screenheight - player.frame_height:
game_over = True
#移动板
calcLevel()
for base in base_group:
base.velocity.y = base_velocity_y[level]
base.Y += base.velocity.y
#改变板的位置(如果碰到边界)
chBase()
screen.fill(final_color)
base_group.draw(screen)
player_group.draw(screen)
image_data = pygame.surfarray.array3d(pygame.display.get_surface())
pygame.display.update()
FPSclock.tick(FPS)
return image_data,reward,terminal,self.score