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)的更多相关文章

  1. python学习心得第三章

    python学习心得第三章 1.三元运算 变量=值1 if 条件 else 值2 由图如果条件成立则赋值1给变量,如果条件不成立则赋值2给变量. 2.数据类型 集合:set() class set(o ...

  2. Objective-C 基础教程第三章,面向对象编程基础知

    目录 Objective-C 基础教程第三章,面向对象编程基础知 0x00 前言 0x01 间接(indirection) 0x02 面向对象编程中使用间接 面向过程编程 面向对象编程 0x03 OC ...

  3. 跟着高淇学Python——第一到第三章总结

    2019/10/26 第一章:Python介绍 Python是一种解释型,面向对象的语言.特点是: 可读性强 简洁,简洁 面向对象 免费开源 可移植性和跨平台性 丰富的库 可扩展性 应用范围:1.人工 ...

  4. 路飞学城-Python爬虫集训-第三章

    这个爬虫集训课第三章的作业讲得是Scrapy 课程主要是使用Scrapy + Redis实现分布式爬虫 惯例贴一下作业: Python爬虫可以使用Requests库来进行简单爬虫的编写,但是Reque ...

  5. python学习笔记——第三章 串

    第三章 字符串学习 1.字符串不灵活, 它不能被分割符值 >>> format = "hello, %s. %s enough for ya?" >> ...

  6. 《零压力学Python》 之 第三章知识点归纳

    第三章(第一个程序)知识点归纳 编程犹如写剧本.Python函数与剧本差别不大,你可以反复调用函数,而它每次都执行预定的“脚本”(脚本也可以指整个程序). 在Python IDLE中,真正的编程是从编 ...

  7. VSTO开发指南(VB2013版) 第三章 Excel编程

    通过前两章的内容,有了一定的基础,但进入第三章,实例的步骤非常多,并且随着VS版本的升级,部分功能菜单界面发生了很大变化,所以,第三章的案例我将逐步编写! 实例3.1的目标就是给Excel写一个加载宏 ...

  8. Python开发【第三章】:Python的文件操作

    一.文件操作模式概述 1.打开文件的模式: r, 只读模式[默认] w,只写模式[不可读:不存在则创建:存在则删除内容:] a, 追加模式[不可读:不存在则创建:存在则只追加内容:] 2." ...

  9. Python开发【第三章】:文件操作

    一.文件操作模式概述 1.打开文件的模式: r, 只读模式[默认] w,只写模式[不可读:不存在则创建:存在则删除内容:] a, 追加模式[不可读:不存在则创建:存在则只追加内容:] 2." ...

  10. python基础教程-第三章-使用字符串

    本章将会介绍如何使用字符串何世华其他的值(如打印特殊格式的字符串),并简单了解下利用字符串的分割.联接.搜索等方法能做些什么 3.1 基本字符串操作 所有标准的序列操作(索引.分片.乘法.判断成员资格 ...

随机推荐

  1. NOIP模拟96

    T1 树上排列 解题思路 是一个一眼切的题目... 看到题目第一眼就是 Deepinc 学长讲的可重集,无序 Hash . 直接套上一颗线段树再加上树剖, \(nlog^2n\) 直接过,好像也可以树 ...

  2. MYSQL 移机重装步骤(windows11)

      MYSQL 移机重装步骤(windows11)   目的:已有电脑 A,D盘安装有mysql(安装方式为免安装) , 准备在另一台电脑B上,复制安装电脑A上的mysql(8.0.23版本) . 要 ...

  3. Your Post Title Here

    VSCode 实时预览还需要执行 Markdown: Open Preview to the Side 命令来实现. 在命令窗口输入 Markdown: Open Preview to the Sid ...

  4. 小米 红米 MIUI 重新打开(开启)蓝牙耳机电量弹窗

    原本关闭了下拉通知栏,显示耳机电量的窗口.想重新开开启. 解决方法: 1.确保小爱同学开了通知权限. 2.在蓝牙-高级设置里-开启"小米快连" 3.手机是解锁状态(非锁屏),耳机需 ...

  5. 【大道至简】NetCore3.1快速开发框架一:介绍

    新的一年开始,祝大家2020新年快乐! 去年开源了一个基于NetCore2.2的框架,好多好基友还是比较喜欢的 github地址:https://github.com/feiyit/FytSoaCms ...

  6. spark读取hive表,org.apache.spark.sql.AnalysisException: Unsupported data source type for direct query on files: hive;

    异常出现:spark读取hive表时,spark.read.table(hive.test) hdp版本的spark默认的catalog是spark,配置项 metastore.catalog.def ...

  7. mysql8.0.22在centos7.6下的简单安装

    如果想把mysql安装得好一些,则严重推荐使用压缩包来安装,不推荐使用rpm方式. 一般情况下,现在大部分的服务器都是x86-64,少数是arm架构的. 选择合适的版本,下载即可. 本文中,使用的是 ...

  8. Redis八股文(大厂面试真题)

    号:tutou123com​我是小宋编码,Java程序员 ,只熬夜但不秃头. 关注我,带你轻松过面试.提升简历亮点如果你觉得对你有帮助,欢迎关注[1] 内容目录 1.说说redis,了解redis源码 ...

  9. 算法金 | A - Z,115 个数据科学 机器学习 江湖黑话(全面)

    大侠幸会,在下全网同名「算法金」 0 基础转 AI 上岸,多个算法赛 Top 「日更万日,让更多人享受智能乐趣」 机器学习本质上和数据科学一样都是依赖概率统计,今天整整那些听起来让人头大的机器学习江湖 ...

  10. 在centos开启防火墙没启动22/tcp or 22/udp的情况下是如何ssh连上的

    偶尔间查询防火墙的22/tcp or 22/udp ,看到是no的状态,而且此时也是ssh登陆的,然后就反复尝试,关闭22端口,开启,重载,重启.甚至连上另个服务器发现还是一样的情况.在群里问大佬们终 ...