# coding=utf-8 #必須指定 # df_maze.py # 21-02-07 cube3.py # 21-02-09 cube5.py #!/usr/bin/env python import numpy as np import sys , traceback , os import pdb from collections import deque import math from struct import * import copy import random if sys.version[0] == '2': import Tkinter as tk else: import tkinter as tk import random from p3drect import Room3d class Tennis(): def __init__(self): self.rm3d = Room3d() # class Room3dの実体化 self.rm3d.c0.title('Tennis Game') self.rm3d.c0.bind("",self.quit) self.rm3d.c0.bind("",self.initmx) self.rm3d.c0.bind("",self.dispval) self.rm3d.c0.bind("",self.init_tennis) self.rm3d.c0.bind("",self.follow) self.rm3d.c0.bind("",self.zoom) self.rm3d.c0.bind("",self.zoom_back) self.rm3d.c0.bind("" ,self.keyup) # 視点の高さ変更 self.rm3d.c0.bind("" ,self.keydown) self.rm3d.c0.bind("" ,self.keyleft) self.rm3d.c0.bind("" ,self.keyright) self.run() # tk.mainloop() def quit(self,event=None): print ("quit") self.rm3d.c0.destroy() sys.exit() def keyup(self,event=None): self.za += 10 print ("za=",self.za) def keydown(self,event=None): self.za -= 10 print ("za=",self.za) def keyleft(self,event=None): self.xa += np.pi/180 print ("xa=%4d" % (self.xa*180/np.pi)) def keyright(self,event=None): self.xa -= np.pi/180 print ("xa=%4d" % (self.xa*180/np.pi)) def initmx(self,event=None): self.rm3d.initmx = True def dispval(self,event=None): print ("main object") self.rm3d.dispwall(self.hoge) print ("sub object") self.rm3d.dispwall(self.subhoge) print ("radius =",self.rm3d.radius) print ("balladrs =",self.balladrs) def init_tennis(self,event=None): self.disp_flag = True pass def follow(self,event=None): if self.follow: self.follow = False else: self.follow = True def zoom(self,event=None): self.rl -= 1 def zoom_back(self,event=None): self.rl += 1 def run(self): self.disp_flag = False plwidth = 40 # player's body width playerheight = 60 player1 = self.generate_monolith(plwidth,15,playerheight,'#ff8c00') player2 = self.generate_monolith(plwidth,15,playerheight,'#00faca') self.ballr = 11 # radius of ball ball = [[[ [ -self.ballr , -self.ballr,-self.ballr ], [ -self.ballr , +self.ballr,-self.ballr ], [ +self.ballr , +self.ballr,+self.ballr ], [ +self.ballr , -self.ballr,+self.ballr ],[0],['#fffefd'],[2] ] ]] # x y cunitw , cunitd = 40,72 # coat cell size cnumw , cnumd = 8, 8 # number of cell coatsize = [cunitw*cnumw , cunitd*cnumd] coatin = [] self.insidex = cunitw self.insidey = cunitd cc = 0 for i in range( cnumw): for j in range( cnumd ): coatin.append([]) x = i*cunitw y = j*cunitd coatin[cc].append([x,y,0]) coatin[cc].append([x+self.insidex,y,0]) coatin[cc].append([x+self.insidex,y+self.insidey,0]) coatin[cc].append([x,y+self.insidey,0]) coatin[cc].append([0]) coatin[cc].append(['#808000']) coatin[cc].append([0]) cc += 1 pass pass coat = [coatin] # ball address self.balladrs = [ 200,200,140] # initial ball position # player1 address self.player1adrs = [0,0,0] self.player2adrs = [coatsize[0],coatsize[1],0] grav = 0.2 # speedv = 1.0 # speedh = 1.0 bangunit = (np.pi/180.0) # 90degree = np.pi/2.0 bang = 15 fence = [[-20,-20],[cunitw*cnumw+20 , cunitd*cnumd+20]] player1sm = 6.0 player2sm = 6.0 sm = 3 smratio = 0.75 player1ball_flag = False distance1 = coatsize[1]*smratio distance2 = coatsize[1]*smratio zinc = 0 self.coe = 0.9 # 反発係数 self.rm3d.dest = [ coatsize[0]/2,coatsize[1]/2,0] # 視線の先の座標 self.za = 100.0 self.rm3d.cposx ,self.rm3d.cposy ,self.rm3d.cposz = fence[1][0],fence[1][1]+200,self.za self.rm3d.cpos = [ self.rm3d.cposx , self.rm3d.cposy , self.rm3d.cposz] self.rl = 400 self.xa = 0 bounce_count = 0 widthmiss1 = 0 widthmiss2 = 0 self.follow = False while True: if self.follow: self.rm3d.dest = self.balladrs # self.rm3d.dest[2] = 0 else: self.rm3d.dest = [ coatsize[0]/2,coatsize[1]/2,0] # 視線の先の座標 self.rm3d.cposx = np.sin(self.xa)*self.rl + self.rm3d.dest[0] self.rm3d.cposy = np.cos(self.xa)*self.rl + self.rm3d.dest[1] self.rm3d.cposz = self.za self.rm3d.cpos = [ self.rm3d.cposx , self.rm3d.cposy , self.rm3d.cposz] # player player1hoge = self.rm3d.solve_pack(player1[0],self.player1adrs) player2hoge = self.rm3d.solve_pack(player2[0],self.player2adrs) # print "player done" ballhoge = self.rm3d.solve_pack(ball[0],self.balladrs) self.subhoge = ballhoge + player1hoge + player2hoge # pdb.set_trace() self.hoge = self.rm3d.solve(coat[0]) # 含まれるレクタングルをスクリーンに射影 doge = self.rm3d.reorder(self.hoge,self.subhoge) # 陰線処理とスプライトオブジェクトの混合 boge = self.rm3d.shift2center(doge) # 拡大率を自動調節 self.rm3d.drawwall(boge) # 表示 #### flying ball xinc = np.sin(bang * bangunit) yinc = np.cos(bang * bangunit) self.balladrs[0] += xinc * sm self.balladrs[1] += yinc * sm self.rm3d.s3.set("x:%5d y:%5d z:%5d bang = %10.5f" % (self.balladrs[0],self.balladrs[1],self.balladrs[2],bang)) #### fence hit if not (fence[0][0] < self.balladrs[0] < fence[1][0]): self.balladrs = [ coatsize[0]/1 , 0,140] bang = 0 player1sm = 3 player2sm = 3 if not (fence[0][1] < self.balladrs[1] < fence[1][1]): self.balladrs = [ coatsize[0]/1 , 0,140] bang = 0 player1sm = 3 player2sm = 3 #### gravity self.balladrs[2] += zinc zinc -= grav #### bounce on coat if self.balladrs[2] < (self.ballr * 2): bounce_count += 1 zinc = -(zinc * self.coe) if player1ball_flag: distance1 = (self.balladrs[1])/bounce_count widthmiss1 = coatsize[0]/2 - self.balladrs[0] # print ("widthmiss1=",widthmiss1) else: distance2 = (coatsize[1] - self.balladrs[1])/bounce_count widthmiss2 = coatsize[0]/2 - self.balladrs[0] # print ("widthmiss2=",widthmiss2) self.rm3d.s2.set("%10.5f %10.5f " % (player1sm,player2sm)) #### follow ball diff1 = self.balladrs[0] - self.player1adrs[0] diff2 = self.balladrs[0] - self.player2adrs[0] self.wksd = 2.0 if diff1 > 5.0: player1inc = self.wksd elif diff1 < -5.0: player1inc = -self.wksd self.player1adrs[0] += player1inc if diff2 > 5.0: player2inc = self.wksd elif diff2 < -5.0: player2inc = -self.wksd self.player2adrs[0] += player2inc #### jump if self.balladrs[1] < self.player1adrs[1]+0.1*coatsize[1]: if self.balladrs[2] > playerheight: pz1inc = 3 else: pz1inc = -2 self.player1adrs[2] += pz1inc if self.player1adrs[2] <= 0: self.player1adrs[2] = 0 pz1inc = 0 if self.balladrs[1] > self.player2adrs[1]-0.1*coatsize[1]: if self.balladrs[2] > playerheight: pz2inc = 3 else: pz2inc = -2 self.player2adrs[2] += pz2inc if self.player2adrs[2] <= 0: self.player2adrs[2] = 0 pz2inc = 0 #### hit racket # print " %6d %6d %6d" % (self.player1adrs[1],self.balladrs[1],self.player2adrs[1]) lim = 30 if self.balladrs[1] < self.player1adrs[1]: if self.player1adrs[0] - plwidth/2 < self.balladrs[0] < self.player1adrs[0] + plwidth/2: diffpos = (coatsize[0]/2 - self.player1adrs[0]) * 0.03 bounce_count = 0 bang = 0 bang += diffpos # print ("diffpos=",diffpos) zinc = 3 player1ball_flag = True sm = player1sm pz1inc = -2 if ((coatsize[1] * smratio) - distance1) > 0: player1sm += 0.2 else: player1sm -= 0.2 elif self.balladrs[1] > self.player2adrs[1]: if self.player2adrs[0] - plwidth/2 < self.balladrs[0] < self.player2adrs[0] + plwidth/2: angrand = random.randint(-5,5) bounce_count = 0 bang = 180 + angrand zinc = 3 player1ball_flag = False sm = player2sm pz2inc = -2 if ((coatsize[1] * smratio) - distance2) > 0: player2sm += 0.2 else: player2sm -= 0.2 if self.disp_flag: self.disp_flag = False print ("zinc=",zinc) pass def generate_monolith(self,mw,md,mh,psc): self.psc = psc md2 = md/2 mw2 = mw/2 # object format # [ # plane [ # obj [ # apec[x,y,z] , # apec[x,y,z] , # apec[x,y,z] , # apec[x,y,z] , # [媒介変数格納用], # [色], # [予備] # solveには、planeのレイヤで渡す packman = [[ # down,up [[-mw2,-md2,0],[+mw2,-md2,0], [+mw2,+md2,0],[-mw2,+md2,0],[0],[self.psc],[0] ], [[-mw2,-md2,mh],[+mw2,-md2,mh], [+mw2,+md2,mh],[-mw2,+md2,mh],[0],[self.psc],[0] ], # front,back [[-mw2,-md2,0],[+mw2,-md2,0], [+mw2,-md2,mh],[-mw2,-md2,mh],[0],[self.psc],[0] ], [[-mw2,+md2,0],[+mw2,+md2,0], [+mw2,+md2,mh],[-mw2,+md2,mh],[0],[self.psc],[0] ], # left right [[-mw2,-md2,0],[-mw2,+md2,0], [-mw2,+md2,mh],[-mw2,-md2,mh],[0],[self.psc],[0] ], [[+mw2,-md2,0],[+mw2,+md2,0], [+mw2,+md2,mh],[+mw2,-md2,mh],[0],[self.psc],[0] ], ]] return packman def HelloWorld(): print ("Hello World!") ex = Tennis() if __name__=="__main__": HelloWorld()