对比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 基本字符串操作 所有标准的序列操作(索引.分片.乘法.判断成员资格 ...
随机推荐
- uniapp+django登录页面实现
前后端联动 概述 以一个简单的登录功能为例说明,uni-app的前后端交互 项目地址: 效果图 前端页面开发 项目地址: 后端页面开发 项目地址: 其他参考资料 1.Django项目和uni-app项 ...
- The solution of P9194
10黑寄. problem & blog 考虑到处理加边并不简单,所以我们可以考虑一个黑点 \(p\),连边\((u,p)(p,v)\). 考虑在现在这棵树上连个点在原图中有变相连相当于有一个 ...
- OpenTelemetry Logging 思维导图,收藏
Log 是最常用.最自然的监控数据类型之一,具有以下的优点: 日志的内容比指标更加丰富,可以提供更多的细节信息,帮助开发人员和运维人员更好地理解应用程序的运行状况,通过日志几乎可以重现.还原系统的完整 ...
- 模拟登录之web监控
1.什么是web监控 zabbix除了能通过 脚本+自定义key,实现服务器数据提取监控以外 也支持对网页的HTTP请求.响应监控. 2.web监控需求 以zabbix-UI页面的登录监控,模拟登录, ...
- requests高级操作
requests的Cookie处理 有时相关的需求会让我们去爬取基于某些用户的相关用户信息,例如爬取张三人人网账户中的个人身份信息.好友账号信息等. 那么这个时候,我们就需要对当前用户进行登录操作,登 ...
- javascript 类class设置访问器setter时出现Maximum call stack size exceeded错误
Maximum call stack size exceeded这个错误的意思是调用栈溢出,但是自己写的代码基本不可能出现.所以可能的原因是A调用了B,然后B再调用A,形成了循环调用.或者说是A自己调 ...
- 增补博客 第三篇 python 英文统计
编写程序实现对特定英文文章(文本文件)的单词数和有效行数的统计,其中要求空行不计数: def count_words_and_lines(file_path): word_count = 0 line ...
- 简约博客V1.1版本上线 + 一套新主题
Tips:当你看到这个提示的时候,说明当前的文章是由原emlog博客系统搬迁至此的,文章发布时间已过于久远,编排和内容不一定完整,还请谅解` 简约博客V1.1版本上线 + 一套新主题 日期:2017- ...
- 呼吁 《上海市卫生健康“信息技术应用创新白皮书》改正 C# 被认定为A 组件是错误认知
近日,<上海市卫生健康"信息技术应用创新"白皮书>(以下简称<白皮书>)正式发布,介绍了"医疗信创核心应用适配方法.公立医院信息系统及全民健康信息 ...
- 详解Web应用安全系列(4)失效的访问控制
在Web安全中,失效的访问控制(也称为权限控制失效或越权访问)是指用户在不具备相应权限的情况下访问了受限制的资源或执行了不允许的操作.这通常是由于Web应用系统未能建立合理的权限控制机制,或者权限控制 ...