Created
August 24, 2019 10:44
-
-
Save pikachu0310/c9ee27bba5ddd9c4fb6ba6e1fe3afb88 to your computer and use it in GitHub Desktop.
log5.py
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
from scene import * | |
import sound | |
import random | |
import time | |
import math | |
''' | |
v0.1 8/20 土台完成 | |
v0.2.0 8/21 ボス追加 攻撃追加 三角関数で簡略化 | |
v0.2.1 8/21 雑魚追加 各敵から攻撃 クリア判定 微調整 | |
''' | |
''' | |
メモ | |
#####追加したobject.<ここ>##### | |
object[i].move | |
object[i].hit_box | |
object[i].frames | |
object[i].hp | |
#####ここまで##### | |
#####objectのリスト##### | |
self.object 全て | |
self.alive_object 消されてない全て | |
self.deleted_object 消された全て | |
self.player プレイヤー | |
self.enemy 敵 | |
self.boss ボス | |
self.attaking プレイヤーの攻撃 | |
self.item アイテム | |
#####ここまで##### | |
''' | |
class MyScene (Scene): ############################################# | |
#セットアップ 初期定義 | |
############################################# | |
def setup(self): | |
#手動定義 | |
self.debug = True | |
self.life = 5 | |
self.addtime = -1 | |
self.attack_speed = 3 | |
self.power_up = 0 | |
self.power = 0 | |
self.boss_life = 1500 | |
self.guruguru1 = 45 | |
self.guruguru2 = 45 | |
#自動定義 | |
self.w = self.size.w | |
self.h = self.size.h | |
self.font = ('Futura', 35) | |
self.frames = 0 | |
self.times = 0 | |
self.times0 = time.time() | |
self.object = [] | |
self.alive_object = [] | |
self.deleted_object = [] | |
self.attaking = [] | |
self.tap_move_before = [0,0] | |
self.tapping = 0 | |
self.mode_gameover = False | |
self.attack_timing = 0 | |
self.before_tap = 0 | |
self.player_type = 0 | |
self.enemy = [] | |
self.boss_died = False | |
self.item = [] | |
#最初に追加しておくオブジェクト | |
##########ラベル | |
#何かと思ったらゲームオーバー表示用だった | |
self.score_label = LabelNode('', ('Futura', 70), parent=self) | |
self.score_label.position = (self.w/2, self.h/2) | |
self.score_label.z_position = 1 | |
#プレイヤー体力ラベル | |
self.life_label = LabelNode('❤'*self.life, self.font, parent=self) | |
self.life_label.position = (self.w/2, self.h-30) | |
self.life_label.z_position = 1 | |
#ボス体力ラベル | |
self.boss_life_label = LabelNode(str(self.boss_life), self.font, parent=self) | |
self.boss_life_label.position = (self.w/2, self.h-60) | |
self.boss_life_label.z_position = 1 | |
##########ラベル終わり | |
##########動く系のオブジェクトの追加 | |
######プレイヤー | |
self.easy_add_object(self.w/2,self.h/ | |
2-300,0,0,1,'spc:PlayerLife2Blue') | |
self.object[len(self.object)-1].anchor_point = 0.5,0.5 | |
self.easy_add_object(self.w/2,self.h/2-300,0,0,0.1,'emj:Red_Circle') | |
self.player = [len(self.object)-2,len(self.object)-1] | |
#####敵っていうかボス | |
self.easy_add_object(self.w/2,self.h-100,1,0,1,'emj:Alien_Monster',-1) | |
self.object[len(self.object)-1].life = self.boss_life | |
self.boss = len(self.object)-1 | |
self.enemy.append(len(self.object)-1) | |
############################################# | |
#メインループ ゲームのコア | |
############################################# | |
#メイン ここからずっと実行されるよ | |
def update(self): | |
if self.mode_gameover: | |
pass | |
else: | |
self.frame() | |
self.move_object() | |
self.check_delete() | |
self.check_hit() | |
self.check_add() | |
self.check_attack() | |
self.check_enemy() | |
if self.debug: | |
self.test() | |
############################################# | |
#核となる定義 | |
############################################# | |
#追加の時短バージョン | |
def easy_add_object(self,*args): | |
li = [len(self.object)] | |
for i in list(args): | |
li.append(i) | |
args = tuple(li) | |
self.add_object() | |
self.change_object(args) | |
#オブジェクトの追加 | |
def add_object(self): | |
i = len(self.object) | |
self.alive_object.append(i) | |
self.object.append(SpriteNode('pzl:BallGray')) | |
self.object[i].move = [0,0] | |
self.object[i].frames = self.frames | |
self.add_child(self.object[i]) | |
#オブジェクトの変更 (i,x,y,mx,my,scale,pzl,hit_box) | |
def change_object(self,**kwargs): | |
if 'i' in kwargs: | |
args | |
if len(args) >= 7: | |
self.object[args[0]].remove_from_parent() | |
self.object[args[0]] = SpriteNode(f'{args[6]}') | |
self.object[args[0]].rotation = math.pi | |
self.object[args[0]].frames = self.frames | |
self.add_child(self.object[args[0]]) | |
if len(args) >= 1: | |
i = args[0] | |
if len(args) >= 3: | |
self.object[i].position = args[1],args[2] | |
if len(args) >= 5: | |
self.object[i].move = [args[3],args[4]] | |
if len(args) >= 6: | |
self.object[i].scale = args[5] | |
if len(args) >= 8: | |
self.object[i].hit_box = args[7] | |
#オブジェクトを消す | |
def delete_object(self,i): | |
self.alive_object.remove(i) | |
if i in self.attaking: | |
self.attaking.remove(i) | |
if i in self.enemy: | |
self.enemy.remove(i) | |
if i in self.item: | |
self.item.remove(i) | |
self.deleted_object.append(i) | |
self.object[i].remove_from_parent() | |
#敵の追加 | |
#[x,y,mx,my,hp,hit_box] | |
def easy_add_enemy(self,*args): | |
if len(args) <= 5: | |
hitbox = -1 | |
else: | |
hitbox = args[5] | |
self.easy_add_object(args[0],args[1],args[2],args[3],1,'spc:PlayerLife1Orange',hitbox) | |
self.object[len(self.object)-1].life = args[4] | |
self.enemy.append(len(self.object)-1) | |
#アイテムの追加 | |
#[x,y,mx,my,hit_box] | |
def easy_add_item(self,*args): | |
if len(args) <= 4: | |
hitbox = 20 | |
else: | |
hitbox = args[4] | |
self.easy_add_object(args[0],args[1],args[2],args[3],0.5,'pzl:Yellow5',hitbox) | |
self.item.append(len(self.object)-1) | |
#オブジェクトを動かす | |
def move_object(self): | |
for i in self.alive_object: | |
if self.object[i].move != [0,0]: | |
self.object[i].position = self.object[i].position.x + self.object[i].move[0], self.object[i].position.y + self.object[i].move[1] | |
#画面外のオブジェクトを消す | |
def check_delete(self): | |
for i in self.alive_object: | |
if self.object[i].position.x <= -5 or self.w+5 <= self.object[i].position.x or self.object[i].position.y <= -5 or self.h+5 <= self.object[i].position.y: | |
self.delete_object(i) | |
############################################# | |
#入力の定義 | |
############################################# | |
#タップ時のオブジェクト移動 | |
def tap(self,x,y): | |
if self.times - self.before_tap <= 0.2: | |
self.double_tap() | |
self.before_tap = self.times | |
if self.tapping == 2: | |
#print(len(self.deleted_object)) | |
#for i in self.player: | |
#self.object[i].position = x,y | |
pass | |
#スライド時のオブジェクト移動 | |
def tap_move(self,x,y): | |
if self.tapping == 1: | |
for i in self.player: | |
if self.tap_move_before != [0,0]: | |
self.object[i].position = self.object[i].position.x + (x - self.tap_move_before[0]), self.object[i].position.y + (y - self.tap_move_before[1]) | |
if self.object[i].position.x <= 5: | |
self.object[i].position = [5,self.object[i].position.y] | |
elif self.object[i].position.x >= self.w-5: | |
self.object[i].position = [self.w-5,self.object[i].position.y] | |
if self.object[i].position.y <= 5: | |
self.object[i].position = [self.object[i].position.x,5] | |
elif self.object[i].position.y >= self.h-5: | |
self.object[i].position = [self.object[i].position.x,self.h-5] | |
self.tap_move_before = [x,y] | |
#指を離した時の処理 | |
def tap_end(self,x,y): | |
self.tap_move_before = [0,0] | |
#ダブルタップゆうよ0.2秒 | |
def double_tap(self): | |
self.change_player_type() | |
############################################# | |
#メインループで動かす定義 | |
############################################# | |
#接触したかの判定 円と円の距離の問題と同じ要領 | |
def check_hit(self): | |
self.check_hit_player() | |
self.check_enemy_hit() | |
self.check_hit_item() | |
#プレイヤーに当たったか | |
def check_hit_player(self): | |
for i in self.alive_object: | |
if i in self.player: | |
pass | |
elif i in self.attaking: | |
pass | |
elif i in self.item: | |
pass | |
else: | |
if ((self.object[i].position.x - self.object[self.player[1]].position.x)**2 + (self.object[i].position.y - self.object[self.player[1]].position.y) **2)**(1/2) <= self.object[i].hit_box: | |
self.player_hit(i) | |
#プレイヤーにぶち当たった時の処理 | |
def player_hit(self,i): | |
self.delete_object(i) | |
self.life -= 1 | |
self.life_label.text = '❤'*self.life | |
sound.play_effect('game:Crashing') | |
self.check_gameover() | |
#敵に当たったか | |
def check_enemy_hit(self): | |
for j in self.enemy: | |
for i in self.attaking: | |
if ((self.object[i].position.x - self.object[j].position.x)**2 + (self.object[i].position.y - self.object[j].position.y) **2)**(1/2) <= self.object[i].hit_box: | |
self.enemy_hit(i,j) | |
#敵にぶち当たった時の処理 | |
def enemy_hit(self,i,j): | |
self.delete_object(i) | |
self.object[j].life -= 1 | |
if self.object[j].life <= 0: | |
try: | |
self.delete_object(j) | |
self.random_add_item(self.object[j].position.x,self.object[j].position.y) | |
except: | |
pass | |
#print(f'未解決エラー:同時接触 (object_id:{j})') | |
if j in [self.boss]: | |
self.boss_life_label.text = str(self.object[self.boss].life) | |
if self.object[self.boss].life <= 0: | |
self.boss_died = True | |
sound.play_effect('8ve:8ve-slide-scissors') | |
#アイテムを取ったか | |
def check_hit_item(self): | |
for i in self.item: | |
if ((self.object[i].position.x - self.object[self.player[1]].position.x)**2 + (self.object[i].position.y - self.object[self.player[1]].position.y) **2)**(1/2) <= self.object[i].hit_box: | |
self.item_hit(i) | |
#アイテムにぶち当たった時の処理 | |
def item_hit(self,i): | |
self.delete_object(i) | |
self.power_up += 1 | |
self.check_power() | |
#ゲームオーバーになる条件 | |
def check_gameover(self): | |
if self.mode_gameover: | |
pass | |
elif self.life <= 0: | |
self.gameover() | |
elif len(self.enemy) == 0: | |
self.gameclear() | |
#ゲームオーバー時の処理 | |
def gameover(self): | |
self.mode_gameover = True | |
for i in self.alive_object: | |
self.delete_object(i) | |
self.score_label.text = 'gameover\n' + str(round(self.times,1)) + 's' | |
sound.play_effect('arcade:Explosion_4') | |
#クリアtodo | |
def gameclear(self): | |
self.mode_gameover = True | |
for i in self.alive_object: | |
self.delete_object(i) | |
self.score_label.text = 'gameclear!\n' + str(round(self.times,1)) + 's' | |
sound.play_effect('arcade:Powerup_2') | |
#弾追加の条件決定 | |
def check_add(self): | |
if self.times >= self.addtime: | |
for i in range(min(round((1/5)*self.addtime*(self.addtime-1)),50)): | |
if self.boss_died: | |
pass | |
else: | |
self.add() | |
self.addtime += 1 | |
#todo | |
for i in self.enemy: | |
if (self.frames - self.object[i].frames) % 150 == 0: | |
self.easy_add_object(self.object[i].position.x,self.object[i].position.y,self.random()*(1+(self.addtime/6)**1.2),-1.5*abs(self.random()*(1+(self.addtime/6)**1.2)),0.5,'spc:LaserRed13',5) | |
self.easy_add_object(self.object[i].position.x,self.object[i].position.y,self.random()*(1+(self.addtime/6)**1.2),-1.5*abs(self.random()*(1+(self.addtime/6)**1.2)),0.5,'spc:LaserRed13',5) | |
#弾追加処理 | |
def add(self): | |
num = self.random() | |
self.easy_add_object(self.object[self.boss].position.x,self.object[self.boss].position.y,self.random()*(1+(self.addtime/6)**1.2),-1*abs(self.random()*(1+(self.addtime/6)**1.2)),0.5,'spc:LaserGreen7',5) | |
#攻撃のタイミング | |
def check_attack(self): | |
if self.tapping >= 1: | |
if self.attack_timing - self.times <= 0: | |
self.attack() | |
self.attack_timing += 60 | |
else: | |
self.attack_timing -= self.attack_speed | |
else: | |
self.attack_timing = 0 | |
#攻撃 | |
def attack(self): | |
sound.play_effect('digital:Laser3') | |
if self.player_type == 0: | |
self.easy_attack(-15,10,0,25) | |
self.easy_attack(-12,20,0,25) | |
self.easy_attack(-6,30,0,25) | |
self.easy_attack(0,50,0,25) | |
self.easy_attack(6,30,0,25) | |
self.easy_attack(12,20,0,25) | |
self.easy_attack(15,10,0,25) | |
for i in range(1): | |
self.guruguru1 -=9 | |
self.easy_attack(-50*self.kaiten(self.guruguru1)[0],-50*self.kaiten(self.guruguru1)[1],0,25,0.5,1) | |
self.easy_attack(50*self.kaiten(self.guruguru1)[0],50*self.kaiten(self.guruguru1)[1],0,25,0.5,1) | |
for i in range(1): | |
self.guruguru2 +=9 | |
self.easy_attack(-50*self.kaiten(self.guruguru2)[0],-50*self.kaiten(self.guruguru2)[1],0,25,0.5,1) | |
self.easy_attack(50*self.kaiten(self.guruguru2)[0],50*self.kaiten(self.guruguru2)[1],0,25,0.5,1) | |
if self.player_type == 1: | |
#self.easy_attack(-15,10,-5,20) | |
#self.easy_attack(-12,20,-3,21) | |
self.easy_attack(0,0,-2,23) | |
self.easy_attack(0,0,0,25) | |
self.easy_attack(0,0,2,23) | |
#self.easy_attack(12,20,3,21) | |
#self.easy_attack(15,10,5,20) | |
for i in [-1,1]: | |
self.guruguru1 -=3 | |
self.easy_attack(-50*self.kaiten(self.guruguru1)[0],-50*self.kaiten(self.guruguru1)[1],i*6,25,0.5,1) | |
self.easy_attack(50*self.kaiten(self.guruguru1)[0],50*self.kaiten(self.guruguru1)[1],i*6,25,0.5,1) | |
for i in [-1,1]: | |
self.guruguru2 +=3 | |
self.easy_attack(-50*self.kaiten(self.guruguru2)[0],-50*self.kaiten(self.guruguru2)[1],i*6,23,0.5,1) | |
self.easy_attack(50*self.kaiten(self.guruguru2)[0],50*self.kaiten(self.guruguru2)[1],i*6,23,0.5,1) | |
#(x,y,mx,my,texture,scale) | |
def easy_attack(self,*args): | |
if len(args) >= 5: | |
scale = args[4] | |
else: | |
scale = 2 | |
if len(args) >= 6: | |
if args[5] == 0: | |
texture = 'spc:Fire5' | |
elif args[5] == 1: | |
texture = 'spc:LaserRed11' | |
else: | |
texture = 'spc:Fire5' | |
self.attaking.append(len(self.object)) | |
self.easy_add_object(self.object[self.player[1]].position.x + args[0],self.object[self.player[1]].position.y + args[1],args[2],args[3],scale,texture,40) | |
def check_enemy(self): | |
if self.object[self.boss].position.x < 20: | |
self.object[self.boss].move = [abs(self.object[self.boss].move[0]),self.object[self.boss].move[1]] | |
elif self.object[self.boss].position.x > self.w-20: | |
self.object[self.boss].move = [-1*abs(self.object[self.boss].move[0]),self.object[self.boss].move[1]] | |
def change_player_type(self): | |
self.player_type += 1 | |
if self.player_type >= 2: | |
self.player_type = 0 | |
def random_add_item(self,x,y): | |
num = random.random() | |
while num > 0: | |
num -= 0.1 | |
self.easy_add_item(x+self.random()*num*100,y+self.random()*num*100,0,-3,20) | |
def check_power(self): | |
self.attack_speed += 0.1 | |
def test(self): | |
if int(self.frames) % 30 == 0: | |
self.easy_add_enemy(self.w/2-100,self.h-20,self.random(),-5*abs(self.random()),10,20) | |
self.easy_add_enemy(self.w/2,self.h-20,self.random(),-5*abs(self.random()),10,20) | |
self.easy_add_enemy(self.w/2+100,self.h-20,self.random(),-5*abs(self.random()),10,20) | |
############################################# | |
############################################# | |
#機種回転可能にする | |
def did_change_size(self): | |
pass | |
#####時短定義 | |
#-1~1の値をランダムで返す | |
def random(self): | |
return (random.random()-0.5)*2 | |
#i度回転させた時の変化の値を返す | |
def kaiten(self,i): | |
return [round(math.cos(math.radians(i)),4),round(math.sin(math.radians(i)),4)] | |
#スピードを回転させる | |
def kaiten_speed(self,i,num): | |
self.object[i].move = [self.object[i].move[0]*self.kaiten(num)[0],self.object[i].move[1]*self.kaiten(num)[1]] | |
#プレイヤーに向ける | |
def aim_to_player(self,x,y): | |
self.object[player[0]].position.x - x | |
pass | |
#todo | |
#ゲームの最小時間単位、フレームの色々 | |
def frame(self): | |
self.frames += 1 | |
self.times = time.time() - self.times0 | |
#タップ時 | |
def touch_began(self, touch): | |
tx = touch.location.x | |
ty = touch.location.y | |
self.tapping += 1 | |
self.tap(tx,ty) | |
#タップでエフェクト表示 | |
self.touch_effect(touch) | |
#スライド時 | |
def touch_moved(self, touch): | |
self.tap_move(touch.location.x,touch.location.y) | |
#指スライドでエフェクト表示 | |
effect = SpriteNode('shp:sun', position=touch.location, parent=self, alpha =0.5, x_scale=0.25, y_scale=0.25) | |
def remove_self(): | |
nonlocal effect | |
effect.remove_from_parent() | |
effect.run_action(Action.sequence( | |
Action.fade_to(0.1, 0.1), | |
Action.call(remove_self))) | |
#タップ類のエフェクト表示処理 | |
def touch_effect(self, touch): | |
effect = SpriteNode('shp:sun', position = touch.location, parent=self, alpha =0.5, x_scale=0.25, y_scale=0.25) | |
def remove_self(): | |
nonlocal effect | |
effect.remove_from_parent() | |
effect.run_action(Action.sequence( | |
Action.fade_to(0.1, 1.0), | |
Action.call(remove_self))) | |
#離す時 | |
def touch_ended(self, touch): | |
self.tapping -= 1 | |
self.tap_end(touch.location.x,touch.location.y) | |
#実行ぅ | |
if __name__ == '__main__': | |
run(MyScene(), show_fps=True) |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment