3.3. 编程实现
2. 控制摩托车和箱子
在这个步骤中,将编程控制摩托车和箱子角色的运动,让摩托车在沙漠公路上能够加速或减速行驶,在碰到箱子时能够停止,以及显示麾托车的行驶速度和里程等。
(1) 创建motor_move()函数,实现对摩托的行驶控制,分别使用键盘上的 4 个方向键控制摩托车向上移动、向下移动、减速和加速。
1 function motor_move(up_max, down_min, speed, key ,dt) 2 #摩托移动''' 3 global motor_speed, motor_bottom 4 if key.UP 5 6 motor_bottom -= 50 * dt 7 #println(motor_bottom) 8 if motor_bottom <HEIGHT-up_max 9 motor_bottom = HEIGHT-up_max 10 end 11 end 12 if key.DOWN 13 motor_bottom += 50 * dt 14 if motor_bottom > down_min 15 motor_bottom = down_min 16 end 17 end 18 if key.LEFT 19 motor_speed -= 324 * dt 20 if motor_speed < 0 21 motor_speed = 0 22 end 23 end 24 if key.RIGHT 25 motor_speed += speed * dt 26 if motor_speed > 1620 27 motor_speed = 1620 #摩托车最大速度 28 end 29 end 30 end
这个函数将会被间接调用,与时间敏感的数据和 dt 参数结合使用,从而精确控制数据的变化。例如,按下向上方向键控制麾托车往窗口上方移动时,在代码 motor_bottom -= 50 * dt 中使用了 dt 参数,假设50是 1s 内的变化量。 也就是说,按下向上方向键,变量 motor_bottom 在 lS 内能够减少50(注意坐标轴是位于窗口左上角)。 其他使用了 dt 参数的代码与之是相同的道理。
(2) 创建motor_control()函数,用于控制麾托车角色运动。根据摩托车与箱子是否碰撞和所处位置使用不同的方式控制摩托车移动,以及显示摩托车的行驶速度和里程等。
1 function motor_control(g::Game,dt) 2 #摩托车的控制''' 3 global motor_speed, motor_left, motor_bottom, mileag-es,isPlaying,speed_label,mileages_label 4 5 #碰撞检测和移动控制 6 if collide(motor, box) 7 #println(@sprintf("box.bottom=%2d,motor.bottom=%2d",box.bottom,motor.bottom)) 8 if ( box.bottom - 24< motor.bottom < box.bottom) 9 #println("oo") 10 motor_speed = 0 11 motor_move(50, HEIGHT, motor_speed,g.keyboard, dt) 12 elseif motor.bottom <= box.bottom - 24 13 motor_move(50, box.bottom - 24, 162,g.keyboard, dt) 14 else 15 motor_move(box.bottom, HEIGHT, 162,g.keyboard, dt) 16 end 17 else 18 motor_move(50, HEIGHT, 162,g.keyboard, dt) 19 end 20 motor.bottom = motor_bottom 21 motor_left += motor_speed * dt 22 mileages = motor_left * 0.024 23 speed_label =TextActor(@sprintf("Motor: %.3f km/h",motor_speed * 0.024 * 3.6),"moonhouse") 24 speed_label.pos=(10,15) 25 mileages_label = TextActor(@sprintf("Mileages: %.3f km" ,mileages / 1000),"moonhouse") 26 mileages_label.pos=(10,35) 27 end
关于控制摩托车运动的几种方式以及将速度和里程转换成km为单位等,请查看编程思路中的介绍 这个函数在窗口update()方法中使用。
(3) 创建box_control()函数,用于控制箱子角色运动。当摩托车行驶里程超过100m,并且里程数是 300 的整数倍时,将让箱子从x坐标3000 处向窗口左侧移动。同时,箱子出现在麾托车y坐标附近。如果玩家不注意控制摩托车行驶,就会撞上箱子。这个函数在窗口update()方法中使用。
1 function box_control(dt) 2 #'''箱子的控制''' 3 global mileages, motor_speed 4 if mileages > 100 && floor(Int,mileages) % 300 == 0 5 println(floor(Int,mileages)) 6 #放置箱子 7 box.left = 3000 8 box.bottom = motor.bottom + 6 9 #播放警报声 10 play_music(alert_sound,3) 11 else 12 #移动箱子 13 box.left -= motor_speed * dt 14 end 15 end
(4) 窗口update()方法
1 function update(g, dt) 2 bgA.pos=(0 - floor(Int,motor_left) % 600, 0) 3 bgB.pos=(600 - floor(Int,motor_left) % 600, 0) 4 motor_control(g,dt) 5 box_control(dt) 6 end
至此,第2个步骤的工作就完成了。运行程序,就可以使用键盘上的4个方向键控制摩托车上下移动、加速或减速,当摩托车碰到箱子时,就会停止前进。同时,在摩托车向前行驶时,窗口左上方的速度和里程数会不断变化。
3. 添加游戏音效
在这个步骤中,将编程实现让麾托车行驶时发出轰鸣的引擎声,以及在靠近箱子时响起警报声,提醒玩家注意躲避。
(1) 在motor_contro()函数中增加播放摩托车音效的代码。当摩托车行驶速度大于0 时,就播放轰鸣的引擎声音效,当行驶速度等于 0 时,则停止声音。
function motor_control(g::Game,dt) #摩托车的控制''' …… if motor_speed > 0 if !isPlaying play_music(motor_sound) isPlaying=true end elseif motor_speed == 0 if isPlaying==true isPlaying=false end end end
(2) 在 box_control()函数中增加播放警报声的代码。当摩托车的行驶里程大于100m,并且是 300 的整数倍时,就播放警报声音效。
1 function box_control(dt) 2 #'''箱子的控制''' 3 global mileages, motor_speed 4 if mileages > 100 && floor(Int,mileages) % 300 == 0 5 println(floor(Int,mileages)) 6 #放置箱子 7 box.left = 3000 8 box.bottom = motor.bottom + 6 9 #播放警报声 10 play_music(alert_sound,3) 11 else 12 #移动箱子 13 box.left -= motor_speed * dt 14 end 15 end
至此,这个“疯狂摩托”游戏程序编写完毕。运行程序,玩家就可以听到摩托车在行驶中发出轰鸣的引擎声,还可以在听到警报声后及时躲避前方出现的箱子。 否则,摩托车在高速行驶时,玩家会很难躲避箱子。