对比python学julia(第三章:游戏编程)--(第四节)捕鱼达人(5)
4.3. 编程实现
(续上)
3. 实现射击捕鱼
在第 3 个阶段,将按照“编程思路”中介绍的射击捕鱼的算法进行编程,实现让玩家操控大炮射击捕鱼。在“bydr”项目目录中,把version2.jl复制一份并命名为version3.jl,然后在第2个版本的基础上编写第3个版本的代码。
1) 创建3个角色
由于GameZero没有精灵(sprite)的概念,所以我们将game_sprites.jl,改名为game_actor.jl,并在其中分别创建BulletSprite()函数生成炮弹角色、NetSprite()函数生成渔网角色和CoinSprite()函数生成硬币角色。
BulletSprite()函数代码如下:
1 function BulletSprite(x,y)
2 #'''炮弹精灵'''
3 actor=Actor(bullet_img)
4 actor.pos=x,y
5 actor.speed = 300
6 actor.alpha=255
7 #self.visible = True
8 return actor
9 end
炮弹角色有两个属性:speed 和 visible,分别用于控制炮弹的移动速度和可见状态。不过GameZero的Actor没有visible属性,但是提供了alpha属性,这个属性可以控制Actor的透明度,alpha的值为0表示完全透明,255表示完全不透明,因此可以用这个属性达到控制炮弹可见性的目的。
另外创建函数fire_move()法用于实现炮弹的移动,当炮弹移动到游戏窗口的可见区域之外,就让其消失。
1 function fire_move(bullet::Actor, dt)
2 #移动炮弹
3 if bullet.alpha==255
4 move(bullet,bullet.speed * dt)
5 if bullet.x < 0 || bullet.x > 1024 || bullet.y > 768
6 #self.visible = False
7 bullet.alpha=0
8 end
9 end
10 end
NetSprite()函数代码如下:
1 function NetSprite(netPos)
2 #'''渔网精灵'''
3 actor=Actor(fishing_net_img,pos=netPos)
4 #self.set_sprite_center()
5 actor.size = 0
6 #actor.visible = True
7 actor.alpha=255
8 return actor
9 end
渔网角色两个属性:size 和 visible,分别用于控制渔网张开的大小和可见性。可见性鱼炮弹类同。
另外,创建open()函数,用于实现让渔网由小慢慢变大并消失的动态效果。
function open(net::Actor, dt)
#打开渔网
if net.scale <= [1,1]
net.size += 300 * dt
net.scale = [net.size / 100,net.size / 100]
else
#net.visible = false
net.alpha=0
end
end
注意Actor的属性scale,可对角色图像进行缩放,它是个含有两个元素的数组,分别为横向和纵向缩放比例,因此它可以非等比缩放。
CoinSprite()函数的代码如下:
1 function CoinSprite(coinPos, score=0)
2 #'''硬币精灵'''
3 #println(silver_coin_img[1])
4 actor=Actor(silver_coin_img[1],pos=coinPos)
5 actor.score = score
6 actor.speed = 400
7 #actor.visible = True
8 actor.alpha=255
9 actor.frame=1
10 actor.set_animation=coin_animation(score,actor)
11 #面向窗口底部的硬币箱
12 point(actor,160, 597)
13 return actor
14 end
硬币角色有3个属性,Score用于记录捕获一条鱼的得分,speed和visible分别用于控制硬币移动速度和可见状态。类中的 set_animation属性用于按得分创建银币或金币的动画图像。
这里就显现出Julia的独特之处了!在Julia中处处皆对象。函数也是对象,因此可以将一个函数作为某个对象的属性。这里,硬币的set_animation属性就被赋予了一个函数
actor.set_animation=coin_animation(score,actor)
而coin_animation()函数是这样的:
function coin_animation(score,coin::Actor)
#'''设置硬币动画'''
images = (score <= 20) ? silver_coin_img : gold_coin_img
function _animation()
_frame=coin.frame
if _frame < length(images)
coin.image = images[_frame]
_frame += 1 else
_frame = 1
end
coin.frame=_frame
schedule_once(_animation, 1/16)
end
return _animation
end
另外,创建move_down()函数,控制硬币的移动,当硬币移动到计分牌下方时,消失。
function move_down(coin::Actor, dt)
#'''移动硬币'''
if coin.y < 600
move(coin,coin.speed * dt)
else
#coin.visible = False
#println(coin.alpha)
coin.alpha=0
end
end
2) 控制射击捕鱼动
切换到“version3.jl”源文件,创建fire_control()函数,用于实现发射炮弹捕鱼,检测炮弹与鱼的碰撞,以及控制渔网张开、硬币落下等。
function fire_control(dt)…end
从 bullets 列表读取各个炮弹精灵实例,让炮弹精灵移动,并与 fishes 列表中的每个鱼角色实例进行碰撞检测。当炮弹角色碰到鱼角色时,就让炮弹消失,并在鱼的位置抛出一张渔网。此外,还从 bullets 列表中移除处于不可见状态的炮弹角色实例。
1 #'''捕鱼控制'''
2 #炮弹
3 for bullet in bullets
4 if bullet.alpha==255
5 #移动炮弹
6 fire_move(bullet,dt)
7 if bullet.y < 150
8 continue
9 end
10 #对每条有生命的鱼进行碰撞检测
11 for fish in fishes
12 if fish.life <= 0
13 continue
14 end
15 if collide(bullet,fish)
16 #命中鱼减去生命值
17 fish.life -= 1
18 #让炮弹消失
19 #bullet.visible = False
20 bullet.alpha=0
21 #抛撒渔网在炮弹处
22 throw_fishing_net(fish.pos)
23 end
24 end
25 else
26 #delete!(bullets,bullet)
27 #bullets.remove(bullet)
28 #bullet.delete()
29 filter!(e->e≠bullet,bullets)
30 end
31 end
从 nets 列表中读取各个渔网角色实例,让渔网逐渐张开。当渔网角色处于不可见状态时,就将其从 nets 列表中移除。
#渔网
for net in nets
if net.alpha==255
open(net,dt)
else
#delete!(nets,net)
#nets.remove(net)
#net.delete()
filter!(e->e≠net,nets)
end
end
从 coins 列表中读取各个硬币角色实例,让硬币角色向着窗口左下角的硬币盒处移动。 之后 ,将捕鱼的得分累加到全局变量 Score 中 ,并将硬币角色从 coins 列表中移除。
global score_label
#硬币
for coin in coins
if coin.alpha==255
move_down(coin,dt)
else
#加分
global score
score += coin.score
score_label = TextActor(@sprintf("%06d",score),"Arial-Black",font_size=24, color=Int[255,255,255,255])
score_label.pos=(165,635)
#score_label.text = '%06d' % score #delete!(coins,coin)
#coins.remove(coin)
#coin.delete()
filter!(e->e≠coin,coins)
end
end
至此,函数 fire_contro1( )编写完毕,在窗口update事件方法里调用。
接下来,创建fire_bullet()、throw_fishing_net()和 release_coin()这3 个函数,分别用于实现发射炮弹、抛出渔网和释放硬币的功能。在这些函数中将会生成炮弹角色、渔网角色和硬币角色的实例,将它们加人到对应的bullets、nets或coins列表中。
function fire_bullet()
#'''发射炮弹'''
#println(cannon.angle) bullet = BulletSprite(0,0)
bullet.angle = cannon.angle
bullet.x=cannon.x+ (cannon.w-bullet.w)/2
bullet.y=cannon.y+ (cannon.h-bullet.h)/2
push!(bullets,bullet)
#bullets.append(bullet)
end function throw_fishing_net(pos)
#'''抛撒渔网'''
net = NetSprite(pos)
push!(nets,net)
#nets.append(net)
end function release_coin(pos, score)
#'''释放金币'''
coin = CoinSprite(pos, score)
coin.set_animation()
#coin_animation(coin,score)
push!(coins,coin)
#coins.append(coin)
end
在游戏窗口中按下鼠标左键时,将调用 fire_bullet() 函数发射炮弹。
function on_mouse_down(g::Game, pos, button)
if button==MouseButtons.LEFT
#println("在窗口'$pos'处按下左键")
fire_bullet()
end
end
还要在游戏窗口的事件draw()方法中调用 draw_actor()函数,将 nets、coins和bullets 这 3 个列表中的渔网、硬币和炮弹角色实例的图像绘制到窗口中。
function draw(g::Game)
clear()
draw_actor(fishes)
draw_actor(nets)
draw_actor(coins)
draw(panel)
draw(score_label)
draw_actor(bullets)
draw(cannon)
end
至此,这个游戏程序的第3个版本完成。运行程序,就能让玩家操控大炮发射炮弹捕鱼了。赶快试试吧!
4. 播放背景音乐
看着赏心悦目的画面,再配上悦耳动听的音乐,将让游戏体验更佳。这是第 4 个阶段要实现的功能,请自行实现。
源码下载:https://files.cnblogs.com/files/zjzkiss/bydr_v3.rar
对比python学julia(第三章:游戏编程)--(第四节)捕鱼达人(5)的更多相关文章
- python学习心得第三章
python学习心得第三章 1.三元运算 变量=值1 if 条件 else 值2 由图如果条件成立则赋值1给变量,如果条件不成立则赋值2给变量. 2.数据类型 集合:set() class set(o ...
- Objective-C 基础教程第三章,面向对象编程基础知
目录 Objective-C 基础教程第三章,面向对象编程基础知 0x00 前言 0x01 间接(indirection) 0x02 面向对象编程中使用间接 面向过程编程 面向对象编程 0x03 OC ...
- 跟着高淇学Python——第一到第三章总结
2019/10/26 第一章:Python介绍 Python是一种解释型,面向对象的语言.特点是: 可读性强 简洁,简洁 面向对象 免费开源 可移植性和跨平台性 丰富的库 可扩展性 应用范围:1.人工 ...
- 路飞学城-Python爬虫集训-第三章
这个爬虫集训课第三章的作业讲得是Scrapy 课程主要是使用Scrapy + Redis实现分布式爬虫 惯例贴一下作业: Python爬虫可以使用Requests库来进行简单爬虫的编写,但是Reque ...
- python学习笔记——第三章 串
第三章 字符串学习 1.字符串不灵活, 它不能被分割符值 >>> format = "hello, %s. %s enough for ya?" >> ...
- 《零压力学Python》 之 第三章知识点归纳
第三章(第一个程序)知识点归纳 编程犹如写剧本.Python函数与剧本差别不大,你可以反复调用函数,而它每次都执行预定的“脚本”(脚本也可以指整个程序). 在Python IDLE中,真正的编程是从编 ...
- VSTO开发指南(VB2013版) 第三章 Excel编程
通过前两章的内容,有了一定的基础,但进入第三章,实例的步骤非常多,并且随着VS版本的升级,部分功能菜单界面发生了很大变化,所以,第三章的案例我将逐步编写! 实例3.1的目标就是给Excel写一个加载宏 ...
- Python开发【第三章】:Python的文件操作
一.文件操作模式概述 1.打开文件的模式: r, 只读模式[默认] w,只写模式[不可读:不存在则创建:存在则删除内容:] a, 追加模式[不可读:不存在则创建:存在则只追加内容:] 2." ...
- Python开发【第三章】:文件操作
一.文件操作模式概述 1.打开文件的模式: r, 只读模式[默认] w,只写模式[不可读:不存在则创建:存在则删除内容:] a, 追加模式[不可读:不存在则创建:存在则只追加内容:] 2." ...
- python基础教程-第三章-使用字符串
本章将会介绍如何使用字符串何世华其他的值(如打印特殊格式的字符串),并简单了解下利用字符串的分割.联接.搜索等方法能做些什么 3.1 基本字符串操作 所有标准的序列操作(索引.分片.乘法.判断成员资格 ...
随机推荐
- 【jetson nano】yolov5环境配置tensorrt部署加速
安装pytorch Nano上预装的Jetpack版本为4.6.1,Python为3.6.9,CUDA环境为10.2.在PyTorch for Jetson中可以下载不同版本的torch,torch& ...
- 解决 idea web项目没有小蓝点的问题
在idea导入web项目,项目没有显示小蓝点,无法添加 java文件和运行.如下图的springboot-schedule 和 springboot-test 都没有蓝点: 解决方案一: 点击 Fil ...
- Yolov8和Yolov10的差异以及后处理实现
Yolo模型可分为4个维度的概念 模型版本.数据集.模型变体(Variants).动态/静态模型. Yolo各模型版本进展历史 Yolov(2015年华盛顿大学的 Joseph Redmon 和 Al ...
- Ubuntu Server LTS 修改网卡ip地址、固定IP
Ubuntu Server LTS 修改网卡ip地址方式.固定IP. 18.04 之前版本通过修改/etc/network/interfaces 方式,18.04 版本开始通过netplan 方式: ...
- [flask]统一API响应格式
前言 在设计API返回内容时,通常需要与前端约定好API返回响应体内容的格式.这样方便前端进行数据反序列化时相应的解析处理,也方便其它服务调用.不同公司有不同的响应内容规范要求,这里以常见的JSON响 ...
- MestReNova14.0中文版安装教程
MestReNova 14是一款专业级的核磁共振(NMR)与质谱(MS)数据分析软件,专注于化合物结构解析和验证.该软件以卓越的谱图处理能力和智能化算法为核心,提供自定义参数调整.自动峰识别.精准积分 ...
- CentOS7安装最新版ruby
背景 直接通过yum安装的ruby版本太低,不能满足redis.fpm等软件的需求. 系统环境 CentOS7 安装步骤 下载ruby http://www.ruby-lang.org/en/down ...
- 基于 Cloudflare Workers 和 cloudflare-docker-proxy 搭建镜像加速服务
本文主要介绍了如何基于 Cloudflare Workers 和 cloudflare-docker-proxy 搭建 dockerhub.gcr.quay 等镜像加速服务. 最近,受限于各种情况,部 ...
- LLM推理 - Nvidia TensorRT-LLM 与 Triton Inference Server
1. LLM部署-TensorRT-LLM与Triton 随着LLM越来越热门,LLM的推理服务也得到越来越多的关注与探索.在推理框架方面,tensorrt-llm是非常主流的开源框架,在Nvidia ...
- Linux设备模型:5、device和device driver
作者:wowo 发布于:2014-4-2 19:28 分类:统一设备模型 http://www.wowotech.net/device_model/device_and_driver.html 前言 ...