Python-使用cocos2d实现的捕鱼游戏

  1 #!/usr/bin/env python
  2 # -*- coding: utf-8 -*-
  3 
  4 import cocos
  5 import random
  6 import pyglet
  7 import os
  8 import math
  9 import time
 10 from cocos.director import director
 11 from cocos import layer
 12 from cocos import scene
 13 from cocos import sprite
 14 from cocos import collision_model as collision
 15 from cocos.scenes.transitions import *
 16 from cocos.audio.pygame import music
 17 from cocos.audio.effect import Effect
 18 from cocos.cocosnode import CocosNode
 19 
 20 
 21 director.init(width=800, height=600, caption="wang and miao", audio_backend="sdl")
 22 working_dir = os.path.dirname(os.path.realpath(__file__))
 23 pyglet.resource.path = [os.path.join(".")]
 24 pyglet.resource.reindex()
 25 image_convert = pyglet.resource.image
 26 WIN_WIDTH, WIN_HEIGHT = director.get_window_size()
 27 score = 0
 28 las_bit = 1
 29 
 30 
 31 class Cannon(sprite.Sprite):
 32     def __init__(self):
 33         super(Cannon, self).__init__('textures/pao5.png')
 34         self.position = WIN_WIDTH//2, 0
 35         self.scale = 0.8
 36         self.angle = 0
 37 
 38     def fire(self, x, y):
 39         tanX = abs(float(y)/(x - self.position[0]+0.001))
 40         radian = math.atan(tanX)
 41         self.angle = 90 - radian*180/math.pi
 42         if x < WIN_WIDTH//2:
 43             self.angle = -self.angle
 44         duration = abs(self.angle) / 200.0
 45         self.do(cocos.actions.RotateTo(self.angle, duration))
 46 
 47 
 48 class Net(sprite.Sprite):
 49     def __init__(self):
 50         super(Net, self).__init__('textures/B5.png')
 51         WIN_WIDTH, WIN_HEIGHT = director.get_window_size()
 52         self.position = WIN_WIDTH//2, 0
 53         self.cshape = collision.AARectShape(cocos.euclid.Vector2(0, 0), self.width//2, self.height//2)
 54         self.schedule(self._update_cshape)
 55 
 56     def _update_cshape(self, dt):
 57         self.cshape.center = collision.eu.Vector2(*self.position)
 58 
 59     def shoot(self, x, y, angle):
 60         tan_corner =float(600)/(400+0.001)
 61         corner_radian = math.atan(tan_corner)
 62         corner_angle = 90 - corner_radian*180/math.pi
 63         if abs(angle) > corner_angle:
 64             mx = WIN_WIDTH + 10 if angle > 0 else -10
 65             my = (WIN_WIDTH//2+10)/(x-WIN_WIDTH//2)*y if angle > 0 else (WIN_WIDTH//2+10)/(WIN_WIDTH//2-x)*y
 66         else:
 67             my = WIN_HEIGHT + 10
 68             mx = WIN_WIDTH//2 + my/y*(x-WIN_WIDTH//2) if angle > 0 else WIN_WIDTH//2 - my/y*(WIN_WIDTH//2-x)
 69         distance = math.sqrt(abs(mx - WIN_WIDTH//2)**2+abs(my)**2)
 70         self.scale = 0.8
 71         times = round(distance / 200)
 72         times = times if times else 1
 73         self.do(cocos.actions.RotateTo(angle, 0)|cocos.actions.MoveTo((mx, my), 0.5*times)+cocos.actions.Delay(0.2)+cocos.actions.CallFunc(self.explode))
 74 
 75     def explode(self):
 76         self.stop()
 77         self.kill()
 78 
 79 
 80 class Fish(sprite.Sprite):
 81     def __init__(self, ft):
 82         self.name = ft
 83         WIN_WIDTH, WIN_HEIGHT = director.get_window_size()
 84         textures = []
 85         for x in range(1, 10):
 86             if ft == 'ballfish':
 87                 fish_path_str = 'textures/ballfish/clownfish_%s.png'
 88             elif ft == 'greenfish':
 89                 x = str(0) + str(x)
 90                 fish_path_str = 'textures/greenfish/fish03_%s.png'
 91             elif ft == 'redfish':
 92                 x = str(0) + str(x)
 93                 fish_path_str = 'textures/redfish/fish02_%s.png'
 94             elif ft == 'swimming' and 0 < x < 5:
 95                 x = 'r' + str(x)
 96                 fish_path_str = 'textures/swimming/shark_%s.png'
 97             else:
 98                 continue
 99             texture = pyglet.resource.image(fish_path_str % x)
100             textures.append(texture)
101         if ft == 'swimming':
102             animation  = pyglet.image.Animation.from_image_sequence(textures, 0.5)
103             super(Fish, self).__init__(animation)
104             self.position = -100, random.randint(120, WIN_HEIGHT-320)
105             self.scale = 0.75        
106         else:
107             self.ds = random.randint(0, 10) * 30
108             animation  = pyglet.image.Animation.from_image_sequence(textures, 0.1)
109             super(Fish, self).__init__(animation)
110             self.position = WIN_WIDTH+100+self.ds, random.randint(100, WIN_HEIGHT-self.height-20)
111             self.scale = 0.5
112         self.cshape = collision.AARectShape(collision.eu.Vector2(0,0), self.width//2, self.height//2)
113         self.schedule(self._update_cshape)
114 
115     def _update_cshape(self, dt):
116         self.cshape.center = collision.eu.Vector2(*self.position)
117 
118     def swim(self, ft):
119         if ft == 'swimming':
120             self.do(cocos.actions.MoveTo((WIN_WIDTH+100, self.position[1]), 18)+cocos.actions.CallFunc(self.shark_btb_action))
121         else:
122             self.do(cocos.actions.MoveTo((-100-self.ds, self.position[1]), 12)+cocos.actions.CallFunc(self.small_fish_btb_action))
123 
124     def shark_btb_action(self):
125         self.do(cocos.actions.RotateTo(180, 0))
126         self.do(cocos.actions.MoveTo((-100, self.position[1]+random.choice([-50, 50])), 18)+cocos.actions.CallFunc(self.explode))
127 
128     def small_fish_btb_action(self):
129         self.do(cocos.actions.RotateTo(180, 0))
130         self.do(cocos.actions.MoveTo((WIN_WIDTH+100, self.position[1]+random.choice([-100, 100])), 12)+cocos.actions.CallFunc(self.explode))
131 
132     def explode(self):
133         self.stop()
134         self.kill()
135 
136 
137 class MenuBackgound(cocos.layer.Layer):
138     def __init__(self):
139         super(MenuBackgound, self).__init__()
140         d_width, d_height = director.get_window_size()
141         background = cocos.sprite.Sprite("textures/menu.png")
142         background.position = d_width//2, d_height//2
143         logo_layer = cocos.sprite.Sprite("textures/logo.png")
144         logo_layer.position = d_width//2 , d_height//2+180
145         self.add(background)
146         self.add(logo_layer)
147 
148 
149 class MainMenu(cocos.menu.Menu):
150     def __init__(self):
151         super(MainMenu, self).__init__()
152         self.font_item['font_size'] = 50
153         self.font_item_selected['font_size'] = 50
154         self.font_item['color'] = (255, 255, 255, 25)
155         self.font_item_selected['color'] = (215, 255, 255, 255)
156 
157         menu_start=cocos.menu.ImageMenuItem('textures/start.png', self.menu_start_callback)
158         menu_setting = cocos.menu.ImageMenuItem('textures/set.png', self.menu_setting_callback)
159         menu_help = cocos.menu.ImageMenuItem('textures/help.png', self.menu_help_callback)
160         self.create_menu([menu_start, menu_setting, menu_help],
161             layout_strategy = cocos.menu.fixedPositionMenuLayout([(420, 339), (420, 220), (420, 100)]),
162             selected_effect=cocos.menu.zoom_in(),
163             unselected_effect=cocos.menu.zoom_out())
164 
165     def menu_start_callback(self):
166         yinxiao=Effect('textures/biu.wav')
167         yinxiao.play()
168         layer = GameLayer()
169         gamemenu = GameMenu()
170         game_scene = scene.Scene(layer)
171         game_scene.add(gamemenu)
172         donghua = TurnOffTilesTransition(game_scene, 1)
173         director.push(donghua)
174 
175     def menu_help_callback(self):
176         yinxiao=Effect('textures/biu.wav')
177         yinxiao.play()
178 
179     def menu_setting_callback(self):
180         yinxiao=Effect('textures/biu.wav')
181         yinxiao.play()
182 
183 
184 class GameMenu(cocos.menu.Menu):
185     def __init__(self):
186         super(GameMenu, self).__init__()
187         self.font_item['font_size'] = 50
188         self.font_item_selected['font_size'] = 50
189         self.font_item['color'] = (255, 255, 255, 25)
190         self.font_item_selected['color'] = (215, 255, 255, 255)
191 
192         exit = cocos.menu.ImageMenuItem("textures/exit.png", self.exit_callback)
193         self.create_menu([exit, ],
194             layout_strategy=cocos.menu.fixedPositionMenuLayout([(80, 532),]),
195             selected_effect=cocos.menu.zoom_in(), 
196             unselected_effect=cocos.menu.zoom_out())
197 
198     def exit_callback(self):
199         director.pop()
200         music.stop()
201 
202 
203 class GameLayer(layer.Layer):
204     is_event_handler = True
205     def __init__(self):
206         self.nets = layer.Layer()
207         self.fishs = layer.Layer()
208         super(GameLayer, self).__init__()
209         self.bg = sprite.Sprite('textures/seaworld.jpg')
210         WIN_WIDTH, WIN_HEIGHT = director.get_window_size()
211         self.bg.position = WIN_WIDTH // 2, WIN_HEIGHT // 2
212         self.add(self.bg)
213         self.cannon = Cannon()
214         self.add(self.cannon)
215 
216         self.create_label()
217         self.create_fish()
218         self.play_bgm()
219         self.adjust_las()
220 
221         self.add(self.nets)
222         self.add(self.fishs)
223         self.schedule(collision_handle, self.nets, self.fishs, self.score_value, self)
224 
225     def create_label(self):
226         pyglet.font.add_file("CroissantD.ttf")
227         self.score_label = cocos.text.Label('Score:', 
228             font_name="Times New Roman",
229             font_size=32,
230             anchor_x='center', anchor_y='center')
231         self.score_label.position = WIN_WIDTH - 150, WIN_HEIGHT -50        
232         self.score_value = cocos.text.Label('0', 
233             font_name="CroissantD",
234             font_size=32,
235             anchor_x='center', anchor_y='center')
236         self.score_value.position = WIN_WIDTH - 60, WIN_HEIGHT - 50
237         self.add(self.score_label)
238         self.add(self.score_value)
239 
240     def create_fish(self):
241         add_small_fish(0, self.fishs)
242         self.schedule_interval(add_small_fish, 3, self.fishs)
243         self.schedule_interval(add_shark, 8, self.fishs)
244 
245     def adjust_las(self):
246         self.do(cocos.actions.Delay(1.5)+cocos.actions.CallFunc(lambda : light_and_shade(0, self.bg)))
247         self.schedule_interval(light_and_shade, 5, self.bg)
248 
249     def play_bgm(self):
250         music.load("textures/bgm.wav".encode())
251         music.play(loops=-1)
252         music.set_volume(2)
253 
254     def open_net(self, x, y):
255         onet = cocos.sprite.Sprite("textures/net.png")
256         onet.position = x, y
257         onet.scale = 0.5
258         self.add(onet)
259         onet.do(cocos.actions.Delay(0.5)+cocos.actions.CallFunc(onet.kill))
260 
261     def on_mouse_motion(self, x, y, dx, dy):
262         self.cannon.fire(x, y)
263 
264     def on_mouse_press(self, x, y, button, modiffiers):
265         self.cannon.fire(x, y)
266         if button == pyglet.window.mouse.LEFT:
267             if len(self.nets.children) >= 3:
268                 return
269             self.net = Net()
270             self.nets.add(self.net)
271             self.net.shoot(x, y, self.cannon.angle)
272 
273 
274 def collision_handle(dt, nets, fishs, label, game_layer):
275     global score
276     for i in nets.children:
277         for j in fishs.children:
278             if i[1].cshape.distance(j[1].cshape) == 0:
279                 i[1].explode()
280                 j[1].stop()
281                 j[1].do(cocos.actions.Delay(0.5)+cocos.actions.CallFunc(j[1].explode))
282                 game_layer.open_net(i[1].position[0], i[1].position[1])
283                 if j[1].name == "swimming":
284                     score = score + 3
285                 else:
286                     score = score + 1
287                 if score > 999:
288                     score = 999
289                 label.element.text = str(score)
290                 break
291 
292 
293 def add_small_fish(dt, fish_layer):
294     if len(fish_layer.children) > 12:
295         return
296     randnum = random.randrange(1, 6)
297     for i in range(randnum):
298         ft = random.choice(['ballfish', 'greenfish', 'redfish'])
299         fish = Fish(ft)
300         fish_layer.add(fish)
301         fish.swim(ft)
302 
303 
304 def add_shark(dt, fish_layer):
305     if len(fish_layer.children) > 12:
306         return
307     ft = "swimming"
308     fish = Fish(ft)
309     fish_layer.add(fish)
310     fish.swim(ft)
311 
312 
313 def light_and_shade(dt, bg):
314     global las_bit
315     if las_bit:
316         bg.do(cocos.actions.FadeTo(127, 3.5))
317         las_bit = las_bit - 1
318     else:
319         bg.do(cocos.actions.FadeTo(255, 3.5))
320         las_bit = las_bit + 1
321 
322 
323 if __name__ == '__main__':
324     menu_bg=MenuBackgound()
325     main_scence = scene.Scene(menu_bg)
326     main_menu = MainMenu()
327     main_scence.add(main_menu)
328     director.run(main_scence)
原文地址:https://www.cnblogs.com/ywfft/p/a20200809.html