按下向上箭头,飞船速度不是一直增加
而且飞船移动的方向是固定的不是有角度的
按下箭头飞船可以飞了,但是不减速
加一个keyup handler就可以啦!可以一直加速,不按的时候也可以减速
按下向下按钮飞船不喷火
如何飞进飞出,完成啦阿拉了!!
现在做导弹,导弹做完了,好像同时按住方向和空格,导弹反向不是很对,有个小角度
现在做声音,声音做完啦啦啦
导弹速度有问题,不喷火,按键不是特别灵活
可以喷火了,但是导弹没有从另外一边飞进来,改sprite类,添加if条件就行啦!!!yeah! Finish!!

Phase one - Spaceship

第一部分控制飞船.飞船行为如下:

  • 左右箭头控制飞船的角度。左键逆时针,右键顺时针.不按的话保持角度.要选择合理的角速度angular velocity
  • 向上箭头控制飞船推进.按下向上的箭头开始推进,松开向上箭头停止推进.推进的时候要有推进火苗,推进停止,火苗没有
  • 推进的时候, 飞船应该向前加速.利用提供的函数angle_to_vector来计算速度,从方向/角度你需要经常实验加速度.来生成一个合理的加速度
  • 记住,飞船的加速度在头朝向的直线方向。 但飞船在它速度的方向移动 能加速度在不同方向而不是你移动的方向是这个游戏的一个特点
  • 你的飞船必须有一定的摩擦力. 这条意味着速度要跟一个小余1的数字相乘。如果不推进的话,最终会停下来。

现在按顺序完成上面的动作,每个步骤需要几行代码,这里有一些建议。

  1. Modify the draw method for the Ship class to draw the ship image (without thrust flames) instead of a circle.  这个函数应该包含飞船的位置和角度。注意角度应该是弧度制,不是度数。由于飞船的draw函数已经被调用了,在draw handler里面,  你现在应该可以看到飞船的图像了。用不同的位置和角度实验飞船。
  2. 完成一个初始版本的update函数。这个版本应该依赖他的速度更新飞船的位置信息,在draw handler里面已经有调用update函数,飞船应该移动响应不同的初始速度。
  3. 修改update函数增加角速度
  4. 飞船可以响应左右箭头。.增加keydown和keyup handler检查箭头按钮。 在Ship类里面添加函数并以恒定数量增加或减小角速度(这些函数的结构可以比较灵活) 在keyboard handler里面适当的调用这些函数。确认你可以按期待的那样将你的飞船转弯。
  5. 修改keyboard handler将飞船的推进器开或者关。添加一个函数到Ship类里面来开关推进器(可以用True 和False决定开关).
  6. 修改飞船的draw函数,当推进器开的时候,画出推进图像。(飞船图像是平铺的,并且包含两种飞船图像)
  7. 修改飞船的thrust函数,当推进器开启的时候播放推进的声音。推进关闭的时候关闭声音。
  8. 添加代码到飞船的update函数来使用angle_to_vetor函数来计算向前的速度,飞船面对的方向依赖飞船的角度。
  9. 下一步,添加代码到飞船的update函数来加快飞船在啥方向呢,向前的速度,当飞船在推进的时候。你将需要更新速度矢量通过一个小的部分向前的加速度,所以飞船的速度不会增加的太快。
  10. 然后修改飞船的update函数所以飞船的位置从一边飞船可以从另一边进来。(使用模运算)
  11. 最终给飞船添加摩擦力到飞船的update函数里面,就像视频里面讲的那样,每个速度组件都乘以一个稍微小于1的数,在每次更新的时候。

Phase two - Rocks

为了完成岩石,我们将使用Sprit类,Sprite的更新函数跟飞船的更新函数很类似. 主要的区别是飞船的速度和角度是由按键控制的。 sprites里面这些参数是随机创造的.岩石的包装跟飞船是相同的。

模板中 全局变量a_rock开始速度是0.我们希望通过计时器每秒产生一个。下周我们将天津多重岩石。这周飞船撞到岩石不好挂掉。下周会挂掉。为了完成岩石,我们有如下建议:

  1. 参考视频,完成Sprite类。 修改draw handler来画出实际的图片并更详细的handler来使sprite移动并旋转, 岩石不加速也没有摩擦力。 所以sprite的update函数比飞船的update函数简单。通过给a_rock不同的初始参数来保证它的行为如你所愿
  2. 完成计时器rock_spawner. 设置a_rock一个新的岩石在每次。(不要忘记声明a_rock作为全局变量在计时器里面) 给岩石随机选择一个速度,位置和角速度。 你想控制这些随机数的范围。 那样的话就游戏就不好玩了.所以要确保你的石头各个方向选择,并且向各方向移动

Phase three - Missiles

为了完成导弹, 我们跟岩石类一样使用sprite类。导弹要有零度的角速度  他要有寿命( 他们应该在确定的时间后消失,不然最终整个屏幕都是导弹了), 这周我们可以先忽视它。 而且现在的话,我们只允许一个单独的导弹并且它不会击毁岩石 ,下周再加更多特性

按空格发射导弹,不是像岩石那样的计时器. 他们应该跟飞船和岩石一样screen wrap.其他过程比较类似:

  1. 在ship类里面添加shoot函数。这应该产生一个新的导弹 (现在只要在a_missile里面代替旧的导弹就行了).  导弹的初始位置应是飞船尖端的大炮他的速度应该是飞船的速度和飞船向前的速度的乘积。
  2. 修改keydown handler来调用shoot函数当空格被按下的时候。
  3. 确认导弹的声音传递给sprite的复位器,这样的话无论啥时候打导弹开火的声音可以播放。

Phase four - User interface

我们RiceRocks简单的展示了剩余的生命数和分数。这周这些元素不用改变。  但是下周要改。添加代码到draw handler里面,使用全局变量作为现在的生命和分数。

Grading rubric - 20 pts total (scaled to 100 pts)

测试同学的项目的时候,有些键盘不支持同时按几个按键,所以按一个按键, 用谷歌浏览器测试项目,要是一定要用火狐,关于声音的评分给满分

  • 1 pt - 程序绘出飞船的形状
  • 1 pt - 没有推进的时候飞船是直线飞行的
  • 1 pt - 按下左边箭头,飞船以恒定速度逆时针旋转。
  • 1 pt - 按下右箭头,飞船以恒定角速度顺时针旋转
  • 1 pt -飞船的方向跟速度是独立的
  • 1 pt - 按下向上按钮,程序画出的飞船喷火。
  • 1 pt - 只有按下向上箭头时候程序发出喷射声音。
  • 1 pt - 按下加速键,飞船向前加速
  • 1 pt - 飞船飞出屏幕一边,从屏幕另一边飞进来
  • 1 pt - 不推进的时候,飞船速度慢慢将为0
  • 1 pt - 程序以图片形式绘出岩石
  • 1 pt - 石块恒定速度直线运动
  • 1 pt - 通过计时器控制,每秒生产一个石块。
  • 1 pt - 岩石生产的位置,旋转方向和速度是随机的
  • 1 pt - 按空格键发射导弹。
  • 1 pt - 飞船尖上的大炮发射导弹
  • 1 pt - 导弹的速度是飞船的速度和它向前的速度的和
  • 1 pt - 飞船发射导弹的时候发出声音
  • 1 pt - 画布左上的位置恰当的画出生命数
  • 1 pt - 画布右上角画出分数 

    岩石不是每秒钟生成1个,岩石的角速度和移动速度不是随机的。如何1s变化一次。timer = simplegui.create_timer(500, timer_handler)
  • 已经可以随机生成,但是不是每秒钟更新速度位置等。岩石完成啦!!不能连续的旋转,
# program template for Spaceship
import simplegui
import math
import random # globals for user interface
WIDTH = 800
HEIGHT = 600
score = 0
lives = 3
time = 0.5 class ImageInfo:
def __init__(self, center, size, radius = 0, lifespan = None, animated = False):
self.center = center
self.size = size
self.radius = radius
if lifespan:
self.lifespan = lifespan
else:
self.lifespan = float('inf')
self.animated = animated def get_center(self):
return self.center def get_size(self):
return self.size def get_radius(self):
return self.radius def get_lifespan(self):
return self.lifespan def get_animated(self):
return self.animated # art assets created by Kim Lathrop, may be freely re-used in non-commercial projects, please credit Kim # debris images - debris1_brown.png, debris2_brown.png, debris3_brown.png, debris4_brown.png
# debris1_blue.png, debris2_blue.png, debris3_blue.png, debris4_blue.png, debris_blend.png
debris_info = ImageInfo([320, 240], [640, 480])#碎片
debris_image = simplegui.load_image("http://commondatastorage.googleapis.com/codeskulptor-assets/lathrop/debris2_blue.png") # nebula images - nebula_brown.png, nebula_blue.png#星云
nebula_info = ImageInfo([400, 300], [800, 600])
nebula_image = simplegui.load_image("http://commondatastorage.googleapis.com/codeskulptor-assets/lathrop/nebula_blue.f2014.png") # splash image
splash_info = ImageInfo([200, 150], [400, 300])
splash_image = simplegui.load_image("http://commondatastorage.googleapis.com/codeskulptor-assets/lathrop/splash.png") # ship image
ship_info = ImageInfo([45, 45], [90, 90], 35)
ship_image = simplegui.load_image("http://commondatastorage.googleapis.com/codeskulptor-assets/lathrop/double_ship.png") # missile image - shot1.png, shot2.png, shot3.png
missile_info = ImageInfo([5,5], [10, 10], 3, 50)
missile_image = simplegui.load_image("http://commondatastorage.googleapis.com/codeskulptor-assets/lathrop/shot2.png") # asteroid images - asteroid_blue.png, asteroid_brown.png, asteroid_blend.png
asteroid_info = ImageInfo([45, 45], [90, 90], 40)
asteroid_image = simplegui.load_image("http://commondatastorage.googleapis.com/codeskulptor-assets/lathrop/asteroid_blue.png") # animated explosion - explosion_orange.png, explosion_blue.png, explosion_blue2.png, explosion_alpha.png
explosion_info = ImageInfo([64, 64], [128, 128], 17, 24, True)
explosion_image = simplegui.load_image("http://commondatastorage.googleapis.com/codeskulptor-assets/lathrop/explosion_alpha.png") # sound assets purchased from sounddogs.com, please do not redistribute
soundtrack = simplegui.load_sound("http://commondatastorage.googleapis.com/codeskulptor-assets/sounddogs/soundtrack.mp3")
missile_sound = simplegui.load_sound("http://commondatastorage.googleapis.com/codeskulptor-assets/sounddogs/missile.mp3")
missile_sound.set_volume(.5)
ship_thrust_sound = simplegui.load_sound("http://commondatastorage.googleapis.com/codeskulptor-assets/sounddogs/thrust.mp3")
explosion_sound = simplegui.load_sound("http://commondatastorage.googleapis.com/codeskulptor-assets/sounddogs/explosion.mp3") # helper functions to handle transformations
def angle_to_vector(ang):
return [math.cos(ang), math.sin(ang)] def dist(p,q):
return math.sqrt((p[0] - q[0]) ** 2+(p[1] - q[1]) ** 2) # Ship class
class Ship:
def __init__(self, pos, vel, angle, image, info):
self.pos = [pos[0],pos[1]]
self.vel = [vel[0],vel[1]]
self.thrust = False
self.angle = angle
self.angle_vel = 0
self.image = image
self.image_center = info.get_center()
self.image_size = info.get_size()
self.radius = info.get_radius() def draw(self,canvas):
#canvas.draw_circle(self.pos, self.radius, 1, "White", "White")
if self.thrust == False:
canvas.draw_image(self.image, self.image_center, self.image_size, self.pos,self.image_size,self.angle)
else:
canvas.draw_image(self.image, [self.image_center[0]+90,self.image_center[1]], self.image_size, self.pos,self.image_size,self.angle) def shoot(self):
global a_missile
a_missile = Sprite([my_ship.pos[0]+30*math.cos(my_ship.angle),my_ship.pos[1]+30*math.sin(my_ship.angle)],[my_ship.vel[0] + 10*math.cos(my_ship.angle), my_ship.vel[1] + 10*math.sin(my_ship.angle)],0,0,missile_image,missile_info)
missile_sound.play() def update(self):
self.pos[0] += self.vel[0]#位置更新
self.pos[1] += self.vel[1] self.angle += self.angle_vel#连续旋转 self.vel[0] *= 0.96#摩擦力更新
self.vel[1] *= 0.96 forward = [math.cos(self.angle), math.sin(self.angle)]
if self.thrust:
self.vel[0] += forward[0]
self.vel[1] += forward[1] if self.pos[0] > WIDTH:
self.pos[0] = 0
elif self.pos[0] < 0:
self.pos[0] = WIDTH
elif self.pos[1] > HEIGHT:
self.pos[1] = 0
elif self.pos[1] < 0:
self.pos[1] = HEIGHT # Sprite class
class Sprite:
def __init__(self, pos, vel, ang, ang_vel, image, info, sound = None):
self.pos = [pos[0],pos[1]]
self.vel = [vel[0],vel[1]]
self.angle = ang
self.angle_vel = ang_vel
self.image = image
self.image_center = info.get_center()
self.image_size = info.get_size()
self.radius = info.get_radius()
self.lifespan = info.get_lifespan()
self.animated = info.get_animated()
self.age = 0
if sound:
sound.rewind()
sound.play() def draw(self, canvas):
#canvas.draw_circle(self.pos, self.radius, 1, "Red", "Red")
canvas.draw_image(self.image, self.image_center, self.image_size, self.pos,self.image_size,self.angle) def update(self):
self.angle += self.angle_vel
self.pos[0] += self.vel[0]
self.pos[1] += self.vel[1] if self.pos[0] > WIDTH:
self.pos[0] = 0
elif self.pos[0] < 0:
self.pos[0] = WIDTH
elif self.pos[1] > HEIGHT:
self.pos[1] = 0
elif self.pos[1] < 0:
self.pos[1] = HEIGHT def draw(canvas):
global time, lives, score # animiate background
time += 1
wtime = (time / 4) % WIDTH
center = debris_info.get_center()
size = debris_info.get_size()
canvas.draw_image(nebula_image, nebula_info.get_center(), nebula_info.get_size(), [WIDTH / 2, HEIGHT / 2], [WIDTH, HEIGHT])
canvas.draw_image(debris_image, center, size, (wtime - WIDTH / 2, HEIGHT / 2), (WIDTH, HEIGHT))
canvas.draw_image(debris_image, center, size, (wtime + WIDTH / 2, HEIGHT / 2), (WIDTH, HEIGHT)) canvas.draw_text("Lives", [50, 50], 20, "White")
canvas.draw_text(str(lives), [50, 70], 20, "White")
canvas.draw_text("Score", [700, 50], 20, "White")
canvas.draw_text(str(score), [700, 70], 20, "White")
# draw ship and sprites
my_ship.draw(canvas)
a_rock.draw(canvas)
a_missile.draw(canvas) # update ship and sprites
my_ship.update()
a_rock.update()
a_missile.update() # timer handler that spawns a rock
def rock_spawner():
global a_rock
a_rock = Sprite([random.randrange(0, HEIGHT), random.randrange(0, WIDTH)], [random.randrange(-100, 100)/100.0, random.randrange(-10, 10)/10.0], 0, random.randrange(-2, 2)/ 10.0, asteroid_image, asteroid_info) # initialize frame
frame = simplegui.create_frame("Asteroids", WIDTH, HEIGHT)
def keydown(key):
if key == simplegui.KEY_MAP["left"]:
my_ship.angle_vel += -0.1
elif key == simplegui.KEY_MAP["right"]:
my_ship.angle_vel += 0.1
elif key == simplegui.KEY_MAP["up"]:
my_ship.thrust = True#加了这一行就可以前进啦!!
ship_thrust_sound.play() elif key == simplegui.KEY_MAP["space"]:
my_ship.shoot() def keyup(key):
if key == simplegui.KEY_MAP["left"]:
my_ship.angle_vel = 0
elif key == simplegui.KEY_MAP["right"]:
my_ship.angle_vel = 0
elif key == simplegui.KEY_MAP["up"]:
my_ship.thrust = False
ship_thrust_sound.pause() frame.set_keydown_handler(keydown)
frame.set_keyup_handler(keyup)
# initialize ship and two sprites
my_ship = Ship([WIDTH / 2, HEIGHT / 2], [0, 0], 0, ship_image, ship_info) a_rock = Sprite([random.randrange(0, HEIGHT), random.randrange(0, WIDTH)], [random.randrange(-10, 10)/10.0, random.randrange(-10, 10)/10.0], 0, random.randrange(-2, 2)/ 10.0, asteroid_image, asteroid_info)
a_missile = Sprite([2 * WIDTH / 3, 2 * HEIGHT / 3], [-1,1], 0, 0, missile_image, missile_info, missile_sound) # register handlers
frame.set_draw_handler(draw) timer = simplegui.create_timer(1000.0, rock_spawner) # get things rolling
timer.start()
frame.start()

  

space ship的更多相关文章

  1. poj 1696 Space Ant (极角排序)

    链接:http://poj.org/problem?id=1696 Space Ant Time Limit: 1000MS   Memory Limit: 10000K Total Submissi ...

  2. POJ 1696 Space Ant(极角排序)

    Space Ant Time Limit: 1000MS   Memory Limit: 10000K Total Submissions: 2489   Accepted: 1567 Descrip ...

  3. poj 1696 Space Ant(模拟+叉积)

    Space Ant Time Limit: 1000MS   Memory Limit: 10000K Total Submissions: 3840   Accepted: 2397 Descrip ...

  4. POJ 1696 Space Ant 卷包裹法

    Space Ant Time Limit: 1000MS   Memory Limit: 10000K Total Submissions: 3316   Accepted: 2118 Descrip ...

  5. B - Space Ant

    The most exciting space discovery occurred at the end of the 20th century. In 1999, scientists trace ...

  6. Space Ant

    Space Ant The most exciting space discovery occurred at the end of the 20th century. In 1999, scient ...

  7. poj1696 Space Ant【计算几何】

    含极角序排序模板.   Space Ant Time Limit: 1000MS   Memory Limit: 10000K Total Submissions: 5334   Accepted:  ...

  8. Space Ant(极角排序)

    Space Ant http://poj.org/problem?id=1696 Time Limit: 1000MS   Memory Limit: 10000K Total Submissions ...

  9. 2018.07.04 POJ 1696 Space Ant(凸包卷包裹)

    Space Ant Time Limit: 1000MS Memory Limit: 10000K Description The most exciting space discovery occu ...

随机推荐

  1. oracle DBA学习方法交流

    你想做什么数据库 Oracle? db2?我是做Oracle的 DB2帮不了你 oracle的体系太庞大了,对于初学者来说,难免会有些无从下手的感觉,什么都想学,结果什么都学不好,所以把学习经验共享一 ...

  2. js上传和预览图片

    [1].[代码] [HTML]代码 跳至 [1] <!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" ...

  3. 2^x mod n = 1

    Time Limit: 2000/1000 MS (Java/Others)    Memory Limit: 65536/32768 K (Java/Others)Total Submission( ...

  4. MapReduce多线程下的错误

    最近在写一个MR调度程序,在以服务进程中同时开启了两个MapReduce线程.这两个MR共享同一份输入源,此时会造成Cast异常: java.lang.ClassCastException: org. ...

  5. 基于Extjs的web表单设计器 第六节——界面框架设计

    基于Extjs的web表单设计器 基于Extjs的web表单设计器 第一节 基于Extjs的web表单设计器 第二节——表单控件设计 基于Extjs的web表单设计器 第三节——控件拖放 基于Extj ...

  6. onclientclick和onclick区别

    OnClientClick是客户端脚本,一般使用javascript,在客户端,也就是IE中运行,点击后马上执行OnClick是服务器端事件处理函数,使用C#或者vb.net,在服务器端,也就是IIS ...

  7. 关于StartCoroutine的简单线程使用

    StartCoroutine在unity3d的帮助中叫做协程,意思就是启动一个辅助的线程. 在C#中直接有Thread这个线程,但是在unity中有些元素是不能操作的.这个时候可以使用协程来完成. 使 ...

  8. 【Linux下进程机制】从一道面试题谈linux下fork的运行机制

    今天一位朋友去一个不错的外企面试linux开发职位,面试官出了一个如下的题目: 给出如下C程序,在linux下使用gcc编译: #include "stdio.h" #includ ...

  9. 不容易系列之(4)——考新郎[HDU2049]

    不容易系列之(4)——考新郎 Time Limit: 2000/1000 MS (Java/Others)    Memory Limit: 65536/32768 K (Java/Others)To ...

  10. lua if

    function fact(n) then else ) end end print("输入一个数") a=io.read("*number") print(f ...