文档章节

用协程手动控制基于Lua的两种框架:Codea和Love2D的流程

FreeBlues
 FreeBlues
发布于 2017/07/06 01:16
字数 821
阅读 45
收藏 0
点赞 0
评论 0

用协程手动控制基于Lua的两种框架:Codea和Love2D的流程

问题来源

最近在 Codea 官网社区看到有人提问如何在 Codea 中实现暂停, 这个帖子 Triggering the pause function Codea has _ FIXED wrote some Lua code

在 Codea 中通过宿主 Objective-C 来控制

最有效的办法当然是通过修改 Lua 的宿主语言 C 来挂起整个虚拟机, 具体方法如下:

Codea 导出的 XCode 项目中打开包含 StandaloneViewController.m 文件, 然后修改这个:

StandaloneViewController *cc=self.viewController

把视图控制器保存到变量 cc 中, 那么暂停只需执行如下语句

cc.paused=YES;

恢复只需执行如下语句:

cc.paused=NO;

这应该是一种比较彻底的解决方法, 不过显然无法在 Lua 中来执行, 在 Lua 中它只能暂停, 无法恢复.

在 Codea 中通过 debug 函数来控制

也有人提出用利用 debug 函数的钩子来实现, 代码如下:

function setup()
    x=10
    y=400
    xv=1
    yv=1
    cnt=0
    sec=10
    debug.sethook(loop,"l")
end

function loop()
    while pause do
        ct=os.time()
        if ct>st+sec then
            pause=false
        end  
    end
end

function draw()
    background(40, 40, 50)
    fill(255)
    text("tap screen to pause for "..sec.." seconds.",WIDTH/2,HEIGHT/2)
    x=x+xv
    if x>WIDTH or x<0 then
        xv=xv*-1
    end
    y=y+yv
    if y>HEIGHT or y<0 then
        yv=yv*-1
    end
    ellipse(x,y,20)
    cnt=cnt+1
    text(cnt,WIDTH/2,HEIGHT-50)
end

function touched(t)
    if t.state==BEGAN then
        st=os.time()
        pause=true
    end
end

这种办法可以在 Codea 内暂停/恢复, 唯一的问题是没办法精确控制, 只能用定时器.

在 Codea 中通过协程来控制

我想到的就是用协程来控制流程, 代码如下:

function setup()
    pause = false
    -- Create a new coroutine for the function f
    co = coroutine.create(f)

    box = { x = 10, y = 10,
            width = 20, height = 20,
            fillColor = color(24, 28, 202, 255) }

    -- Here we can not use tween.
    -- t = tween(10, box, {x = 1000, y = 1000})
end

-- Put all your draw code in f
function f()
    while not pause do

        background()
        fontSize(40)
        fill(0,255,0)
        text(os.time(),WIDTH/2,HEIGHT/2)

        fill(box.fillColor)
        box.x, box.y = box.x+1,box.y+1
        rect(box.x,box.y,box.width,box.height)

        coroutine.yield()
    end
end

function draw()
    if not pause then
        coroutine.resume(co)
    end
end

function touched(t)
    -- Click left screen to pause, click right screen to resume
    if t.state == BEGAN and t.x >=WIDTH/2 then
        pause = false
    elseif t.state == BEGAN and t.x <WIDTH/2 then
        pause = true
    end
end

用协程的优点是可以精确地控制流程, 缺点是所有的地方都要考虑到, 另外一个问题就是可能带来性能损失.

在 Love2D 中通过协程来控制

上面的代码稍作修改就可以用在 Love2D 中, 修改后的代码如下:


function love.load()
	canvas = love.graphics.newCanvas(800, 600)
	
	love.graphics.setBackgroundColor(0, 0, 0)
    pause = false
    -- Create a new coroutine for the function f
    co = coroutine.create(f)

    box = { x = 10, y = 10, width = 20, height = 20}
end

function f()
    while not pause do
    	--love.graphics.setCanvas(canvas)
    	love.graphics.setBlendMode("alpha")
		love.graphics.setColor(255, 255, 0)
		love.graphics.print(os.time(), 300,400)
        love.graphics.setColor(0, 255, 0)
        box.x, box.y = box.x+1,box.y+1
        love.graphics.rectangle("fill", box.x, box.y, box.width, box.height)
        --love.graphics.setCanvas()
        
        love.graphics.setBlendMode("alpha")

		--love.graphics.draw(canvas)
        coroutine.yield()
    end
end

function love.draw()
	if not pause then
        coroutine.resume(co)
    end
end

function love.update(delta)	
	if love.keyboard.isDown("p") then
		pause = true
	elseif love.keyboard.isDown("s") then
		pause = false
	end	
end

唯一的问题就是每当暂停时, 屏幕就不显示任何内容了, 这种情况显然是因为我对 Love2D 的处理机制理解存在一些小问题, 有时间了再慢慢分析.

© 著作权归作者所有

共有 人打赏支持
FreeBlues
粉丝 94
博文 269
码字总数 487443
作品 0
其它
程序员
用 Lua 的协程 coroutine 控制 Codea 屏幕刷新速度

用 Lua 的协程 coroutine 控制 Codea 屏幕刷新速度 概述 在 中, 函数 缺省每秒执行 次, 我们希望能修改一下它的刷新速度, 于是想到了 的一个特性:, 希望试着用它来控制程序执行的节奏, 不过目...

FreeBlues ⋅ 2016/06/14 ⋅ 0

从零开始写一个武侠冒险游戏-5-使用协程

从零开始写一个武侠冒险游戏-5-使用协程 ---- 用协程实现控制权灵活切换 概述 因为我们的地图类是可以自己控制大小的, 在无意中用了一个比较大的数字 后, 结果花了挺长时间来生成地图, 而在这...

FreeBlues ⋅ 2016/06/15 ⋅ 0

从零开始写一个武侠冒险游戏-0-开发框架Codea简介

从零开始写一个武侠冒险游戏-0-开发框架Codea简介 概述 本游戏全程使用一款运行于 上的开发工具类 -- 来开发, 是一款 + 的开发工具, 它既是一个: - 也是一个: - 还是一个: - 更是一个: - , 可...

FreeBlues ⋅ 2016/06/21 ⋅ 0

用 Lua 的协程 coroutine 在 Codea 上实现一个多任务调度类

用 Lua 的协程 coroutine 在 Codea 上实现一个多任务调度类 概述 问题描述 在 中调试程序时发现一个问题: 如果在 中执行了比较耗时的语句, 比如地图生成, 资源下载等操作, 那么在该这些操作没...

FreeBlues ⋅ 2016/06/15 ⋅ 0

python 高性能编程之协程

用 greenlet 协程处理异步事件 自从 PyCon 2011 协程成为热点话题以来,我一直对此有着浓厚的兴趣。为了异步,我们曾使用多线程编程。然而线程在有着 GIL 的 Python 中带来的性能瓶颈和多线程...

passionfly ⋅ 2015/05/07 ⋅ 0

并发编程学习总结

我看书有个特点,不写笔记,就感觉好像没有看过书,印象不深刻(虽然写了也未必深刻),所以我看书会比较慢,笔记会很多。这里总结一下并发。 最近学习《深入理解计算机系统》,最后一章中讲...

晨曦之光 ⋅ 2012/06/06 ⋅ 0

并发流程控制--cocoflow

Concurrency Control Flow 并发流程控制 一个基于协程和libuv的C++框架,仅通过 start、 await、 allof、 any_of 控制流程。 基于 协程(Coroutine) & libuv 的C++开发框架 使用 start | awai...

chishaxie ⋅ 2013/10/21 ⋅ 0

对协程的一些理解

协程 协程(coroutine)最早由Melvin Conway在1963年提出并实现,一句话定义:协程是用户态的轻量级的线程 线程和协程 线程和协程经常被放在一起比较;线程一旦被创建出来,编写者是无法决定什...

ksfzhaohui ⋅ 2016/12/09 ⋅ 16

aLiLua v0.44 开发版本发布 (高性能Web服务器)

aLiLua 是一套基于 Linux/epoll/Lua 构建的网络服务开发框架 aLiLua 使用 epoll 进行网络/文件IO事件读写,对Lua协程进行调度,其性能高效并且简单 下载地址: https://github.com/oneoo/ali...

oneoo ⋅ 2014/06/13 ⋅ 12

aLiLua v0.49 稳定版发布 (高性能Web服务器)

aLiLua 是一套基于 Linux/epoll/Lua 构建的网络服务开发框架 aLiLua 使用 epoll 进行网络/文件IO事件读写,对Lua协程进行调度,其性能高效并且简单 下载地址: https://github.com/oneoo/ali...

oneoo ⋅ 2015/01/04 ⋅ 26

没有更多内容

加载失败,请刷新页面

加载更多

下一页

使用 vue-cli 搭建项目

vue-cli 是一个官方发布 vue.js 项目脚手架,使用 vue-cli 可以快速创建 vue 项目,GitHub地址是:https://github.com/vuejs/vue-cli 一、 安装 node.js 首先需要安装node环境,可以直接到中...

初学者的优化 ⋅ 7分钟前 ⋅ 0

设计模式 之 享元模式

设计模式 之 享元模式 定义 使用共享技术来有效地支持大量细粒度对象的复用 关键点:防止类多次创建,造成内存溢出; 使用享元模式来将内部状态与外部状态进行分离,在循环创建对象的环境下,...

GMarshal ⋅ 22分钟前 ⋅ 0

SpringBoot集成Druid的最简单的小示例

参考网页 https://blog.csdn.net/king_is_everyone/article/details/53098350 建立maven工程 Pom文件 <?xml version="1.0" encoding="UTF-8"?> <project xmlns="http://maven.apache.org/POM......

karma123 ⋅ 今天 ⋅ 0

Java虚拟机基本结构的简单记忆

Java堆:一般是放置实例化的对象的地方,堆分新生代和老年代空间,不断未被回收的对象越老,被放入老年代空间。分配最大堆空间:-Xmx 分配初始堆空间:-Xms,分配新生代空间:-Xmn,新生代的大小一...

算法之名 ⋅ 今天 ⋅ 0

OSChina 周日乱弹 —— 这么好的姑娘都不要了啊

Osc乱弹歌单(2018)请戳(这里) 【今日歌曲】 @TigaPile :分享曾惜的单曲《讲真的》 《讲真的》- 曾惜 手机党少年们想听歌,请使劲儿戳(这里) @首席搬砖工程师 :怎样约女孩子出来吃饭,...

小小编辑 ⋅ 今天 ⋅ 8

Jenkins实践3 之脚本

#!/bin/sh# export PROJ_PATH=项目路径# export TOMCAT_PATH=tomcat路径killTomcat(){pid=`ps -ef | grep tomcat | grep java|awk '{print $2}'`echo "tom...

晨猫 ⋅ 今天 ⋅ 0

Spring Bean的生命周期

前言 Spring Bean 的生命周期在整个 Spring 中占有很重要的位置,掌握这些可以加深对 Spring 的理解。 首先看下生命周期图: 再谈生命周期之前有一点需要先明确: Spring 只帮我们管理单例模...

素雷 ⋅ 今天 ⋅ 0

zblog2.3版本的asp系统是否可以超越卢松松博客的流量[图]

最近访问zblog官网,发现zlbog-asp2.3版本已经进入测试阶段了,虽然正式版还没有发布,想必也不久了。那么作为aps纵横江湖十多年的今天,blog2.2版本应该已经成熟了,为什么还要发布这个2.3...

原创小博客 ⋅ 今天 ⋅ 0

聊聊spring cloud的HystrixCircuitBreakerConfiguration

序 本文主要研究一下spring cloud的HystrixCircuitBreakerConfiguration HystrixCircuitBreakerConfiguration spring-cloud-netflix-core-2.0.0.RELEASE-sources.jar!/org/springframework/......

go4it ⋅ 今天 ⋅ 0

二分查找

二分查找,也称折半查找、二分搜索,是一种在有序数组中查找某一特定元素的搜索算法。搜素过程从数组的中间元素开始,如果中间元素正好是要查找的元素,则搜素过程结束;如果某一特定元素大于...

人觉非常君 ⋅ 今天 ⋅ 0

没有更多内容

加载失败,请刷新页面

加载更多

下一页

返回顶部
顶部