Linux DMA:使用DMAengine进行分散 - 收集事务(Linux DMA: Using the DMAengine for scatter-gather transactions)
我尝试使用自定义内核驱动程序中的DMAengine API来执行分散 - 收集操作。 我有一个连续的内存区域作为源,我想通过分散列表结构将其数据复制到几个分布式缓冲区中。 DMA控制器是支持DMAengine API的PL330(参见PL330 DMA控制器 )。
我的测试代码如下:
在我的驱动程序头文件(
test_driver.h
)中:#ifndef __TEST_DRIVER_H__ #define __TEST_DRIVER_H__ #include <linux/platform_device.h> #include <linux/device.h> #include <linux/scatterlist.h> #include <linux/dma-mapping.h> #include <linux/dmaengine.h> #include <linux/of_dma.h> #define SG_ENTRIES 3 #define BUF_SIZE 16 #define DEV_BUF 0x10000000 struct dma_block { void * data; int size; }; struct dma_private_info { struct sg_table sgt; struct dma_block * blocks; int nblocks; int dma_started; struct dma_chan * dma_chan; struct dma_slave_config dma_config; struct dma_async_tx_descriptor * dma_desc; dma_cookie_t cookie; }; struct test_platform_device { struct platform_device * pdev; struct dma_private_info dma_priv; }; #define _get_devp(tdev) (&((tdev)->pdev->dev)) #define _get_dmapip(tdev) (&((tdev)->dma_priv)) int dma_stop(struct test_platform_device * tdev); int dma_start(struct test_platform_device * tdev); int dma_start_block(struct test_platform_device * tdev); int dma_init(struct test_platform_device * tdev); int dma_exit(struct test_platform_device * tdev); #endif
在我的源代码中包含dma函数(
dma_functions.c
):#include <linux/slab.h> #include "test_driver.h" #define BARE_RAM_BASE 0x10000000 #define BARE_RAM_SIZE 0x10000000 struct ram_bare { uint32_t * __iomem map; uint32_t base; uint32_t size; }; static void dma_sg_check(struct test_platform_device * tdev) { struct dma_private_info * dma_priv = _get_dmapip(tdev); struct device * dev = _get_devp(tdev); uint32_t * buf; unsigned int bufsize; int nwords; int nbytes_word = sizeof(uint32_t); int nblocks; struct ram_bare ramb; uint32_t * p; int i; int j; ramb.map = ioremap(BARE_RAM_BASE,BARE_RAM_SIZE); ramb.base = BARE_RAM_BASE; ramb.size = BARE_RAM_SIZE; dev_info(dev,"nblocks: %d \n",dma_priv->nblocks); p = ramb.map; nblocks = dma_priv->nblocks; for( i = 0 ; i < nblocks ; i++ ) { buf = (uint32_t *) dma_priv->blocks[i].data; bufsize = dma_priv->blocks[i].size; nwords = dma_priv->blocks[i].size/nbytes_word; dev_info(dev,"block[%d],size %d: ",i,bufsize); for ( j = 0 ; j < nwords; j++, p++) { dev_info(dev,"DMA: 0x%x, RAM: 0x%x",buf[j],ioread32(p)); } } iounmap(ramb.map); } static int dma_sg_exit(struct test_platform_device * tdev) { struct dma_private_info * dma_priv = _get_dmapip(tdev); int ret = 0; int i; for( i = 0 ; i < dma_priv->nblocks ; i++ ) { kfree(dma_priv->blocks[i].data); } kfree(dma_priv->blocks); sg_free_table(&(dma_priv->sgt)); return ret; } int dma_stop(struct test_platform_device * tdev) { struct dma_private_info * dma_priv = _get_dmapip(tdev); struct device * dev = _get_devp(tdev); int ret = 0; dma_unmap_sg(dev,dma_priv->sgt.sgl,\ dma_priv->sgt.nents, DMA_FROM_DEVICE); dma_sg_exit(tdev); dma_priv->dma_started = 0; return ret; } static void dma_callback(void * param) { enum dma_status dma_stat; struct test_platform_device * tdev = (struct test_platform_device *) param; struct dma_private_info * dma_priv = _get_dmapip(tdev); struct device * dev = _get_devp(tdev); dev_info(dev,"Checking the DMA state....\n"); dma_stat = dma_async_is_tx_complete(dma_priv->dma_chan,\ dma_priv->cookie, NULL, NULL); if(dma_stat == DMA_COMPLETE) { dev_info(dev,"DMA complete! \n"); dma_sg_check(tdev); dma_stop(tdev); } else if (unlikely(dma_stat == DMA_ERROR)) { dev_info(dev,"DMA error! \n"); dma_stop(tdev); } } static void dma_busy_loop(struct test_platform_device * tdev) { struct dma_private_info * dma_priv = _get_dmapip(tdev); struct device * dev = _get_devp(tdev); enum dma_status status; int status_change = -1; do { status = dma_async_is_tx_complete(dma_priv->dma_chan, dma_priv->cookie, NULL, NULL); switch(status) { case DMA_COMPLETE: if(status_change != 0) dev_info(dev,"DMA status: COMPLETE\n"); status_change = 0; break; case DMA_PAUSED: if (status_change != 1) dev_info(dev,"DMA status: PAUSED\n"); status_change = 1; break; case DMA_IN_PROGRESS: if(status_change != 2) dev_info(dev,"DMA status: IN PROGRESS\n"); status_change = 2; break; case DMA_ERROR: if (status_change != 3) dev_info(dev,"DMA status: ERROR\n"); status_change = 3; break; default: dev_info(dev,"DMA status: UNKNOWN\n"); status_change = -1; break; } } while(status != DMA_COMPLETE); dev_info(dev,"DMA transaction completed! \n"); } static int dma_sg_init(struct test_platform_device * tdev) { struct dma_private_info * dma_priv = _get_dmapip(tdev); struct scatterlist *sg; int ret = 0; int i; ret = sg_alloc_table(&(dma_priv->sgt), SG_ENTRIES, GFP_ATOMIC); if(ret) goto out_mem2; dma_priv->nblocks = SG_ENTRIES; dma_priv->blocks = (struct dma_block *) kmalloc(dma_priv->nblocks\ *sizeof(struct dma_block), GFP_ATOMIC); if(dma_priv->blocks == NULL) goto out_mem1; for( i = 0 ; i < dma_priv->nblocks ; i++ ) { dma_priv->blocks[i].size = BUF_SIZE; dma_priv->blocks[i].data = kmalloc(dma_priv->blocks[i].size, GFP_ATOMIC); if(dma_priv->blocks[i].data == NULL) goto out_mem3; } for_each_sg(dma_priv->sgt.sgl, sg, dma_priv->sgt.nents, i) sg_set_buf(sg,dma_priv->blocks[i].data,dma_priv->blocks[i].size); return ret; out_mem3: i--; while(i >= 0) kfree(dma_priv->blocks[i].data); kfree(dma_priv->blocks); out_mem2: sg_free_table(&(dma_priv->sgt)); out_mem1: ret = -ENOMEM; return ret; } static int _dma_start(struct test_platform_device * tdev,int block) { struct dma_private_info * dma_priv = _get_dmapip(tdev); struct device * dev = _get_devp(tdev); int ret = 0; int sglen; /* Step 1: Allocate and initialize the SG list */ dma_sg_init(tdev); /* Step 2: Map the SG list */ sglen = dma_map_sg(dev,dma_priv->sgt.sgl,\ dma_priv->sgt.nents, DMA_FROM_DEVICE); if(! sglen) goto out2; /* Step 3: Configure the DMA */ (dma_priv->dma_config).direction = DMA_DEV_TO_MEM; (dma_priv->dma_config).src_addr_width = DMA_SLAVE_BUSWIDTH_4_BYTES; (dma_priv->dma_config).src_maxburst = 1; (dma_priv->dma_config).src_addr = (dma_addr_t) DEV_BUF; dmaengine_slave_config(dma_priv->dma_chan, \ &(dma_priv->dma_config)); /* Step 4: Prepare the SG descriptor */ dma_priv->dma_desc = dmaengine_prep_slave_sg(dma_priv->dma_chan, \ dma_priv->sgt.sgl, dma_priv->sgt.nents, DMA_DEV_TO_MEM, \ DMA_PREP_INTERRUPT | DMA_CTRL_ACK); if (dma_priv->dma_desc == NULL) { dev_err(dev,"DMA could not assign a descriptor! \n"); goto out1; } /* Step 5: Set the callback method */ (dma_priv->dma_desc)->callback = dma_callback; (dma_priv->dma_desc)->callback_param = (void *) tdev; /* Step 6: Put the DMA descriptor in the queue */ dma_priv->cookie = dmaengine_submit(dma_priv->dma_desc); /* Step 7: Fires the DMA transaction */ dma_async_issue_pending(dma_priv->dma_chan); dma_priv->dma_started = 1; if(block) dma_busy_loop(tdev); return ret; out1: dma_stop(tdev); out2: ret = -1; return ret; } int dma_start(struct test_platform_device * tdev) { return _dma_start(tdev,0); } int dma_start_block(struct test_platform_device * tdev) { return _dma_start(tdev,1); } int dma_init(struct test_platform_device * tdev) { int ret = 0; struct dma_private_info * dma_priv = _get_dmapip(tdev); struct device * dev = _get_devp(tdev); dma_priv->dma_chan = dma_request_slave_channel(dev, \ "dma_chan0"); if (dma_priv->dma_chan == NULL) { dev_err(dev,"DMA channel busy! \n"); ret = -1; } dma_priv->dma_started = 0; return ret; } int dma_exit(struct test_platform_device * tdev) { int ret = 0; struct dma_private_info * dma_priv = _get_dmapip(tdev); if(dma_priv->dma_started) { dmaengine_terminate_all(dma_priv->dma_chan); dma_stop(tdev); dma_priv->dma_started = 0; } if(dma_priv->dma_chan != NULL) dma_release_channel(dma_priv->dma_chan); return ret; }
在我的驱动程序源文件(
test_driver.c
)中:#include <linux/kernel.h> #include <linux/module.h> #include <linux/init.h> #include <linux/version.h> #include <linux/device.h> #include <linux/platform_device.h> #include <linux/of_device.h> #include <linux/of_address.h> #include <linux/of_irq.h> #include <linux/interrupt.h> #include "test_driver.h" static int dma_block=0; module_param_named(dma_block, dma_block, int, 0444); static struct test_platform_device tdev; static struct of_device_id test_of_match[] = { { .compatible = "custom,test-driver-1.0", }, {} }; static int test_probe(struct platform_device *op) { int ret = 0; struct device * dev = &(op->dev); const struct of_device_id *match = of_match_device(test_of_match, &op->dev); if (!match) return -EINVAL; tdev.pdev = op; dma_init(&tdev); if(dma_block) ret = dma_start_block(&tdev); else ret = dma_start(&tdev); if(ret) { dev_err(dev,"Error to start DMA transaction! \n"); } else { dev_info(dev,"DMA OK! \n"); } return ret; } static int test_remove(struct platform_device *op) { dma_exit(&tdev); return 0; } static struct platform_driver test_platform_driver = { .probe = test_probe, .remove = test_remove, .driver = { .name = "test-driver", .owner = THIS_MODULE, .of_match_table = test_of_match, }, }; static int test_init(void) { platform_driver_register(&test_platform_driver); return 0; } static void test_exit(void) { platform_driver_unregister(&test_platform_driver); } module_init(test_init); module_exit(test_exit); MODULE_AUTHOR("klyone"); MODULE_DESCRIPTION("DMA SG test module"); MODULE_LICENSE("GPL");
但是,DMA从不调用我的回调函数,我不知道它为什么会发生。 也许,我误解了一些事情......
谁能帮助我?
提前致谢。
I try to use the DMAengine API from a custom kernel driver to perform a scatter-gather operation. I have a contiguous memory region as source and I want to copy its data in several distributed buffers through a scatterlist structure. The DMA controller is the PL330 one that supports the DMAengine API (see PL330 DMA controller).
My test code is the following:
In my driver header file (
test_driver.h
):#ifndef __TEST_DRIVER_H__ #define __TEST_DRIVER_H__ #include <linux/platform_device.h> #include <linux/device.h> #include <linux/scatterlist.h> #include <linux/dma-mapping.h> #include <linux/dmaengine.h> #include <linux/of_dma.h> #define SG_ENTRIES 3 #define BUF_SIZE 16 #define DEV_BUF 0x10000000 struct dma_block { void * data; int size; }; struct dma_private_info { struct sg_table sgt; struct dma_block * blocks; int nblocks; int dma_started; struct dma_chan * dma_chan; struct dma_slave_config dma_config; struct dma_async_tx_descriptor * dma_desc; dma_cookie_t cookie; }; struct test_platform_device { struct platform_device * pdev; struct dma_private_info dma_priv; }; #define _get_devp(tdev) (&((tdev)->pdev->dev)) #define _get_dmapip(tdev) (&((tdev)->dma_priv)) int dma_stop(struct test_platform_device * tdev); int dma_start(struct test_platform_device * tdev); int dma_start_block(struct test_platform_device * tdev); int dma_init(struct test_platform_device * tdev); int dma_exit(struct test_platform_device * tdev); #endif
In my source that contains the dma functions (
dma_functions.c
):#include <linux/slab.h> #include "test_driver.h" #define BARE_RAM_BASE 0x10000000 #define BARE_RAM_SIZE 0x10000000 struct ram_bare { uint32_t * __iomem map; uint32_t base; uint32_t size; }; static void dma_sg_check(struct test_platform_device * tdev) { struct dma_private_info * dma_priv = _get_dmapip(tdev); struct device * dev = _get_devp(tdev); uint32_t * buf; unsigned int bufsize; int nwords; int nbytes_word = sizeof(uint32_t); int nblocks; struct ram_bare ramb; uint32_t * p; int i; int j; ramb.map = ioremap(BARE_RAM_BASE,BARE_RAM_SIZE); ramb.base = BARE_RAM_BASE; ramb.size = BARE_RAM_SIZE; dev_info(dev,"nblocks: %d \n",dma_priv->nblocks); p = ramb.map; nblocks = dma_priv->nblocks; for( i = 0 ; i < nblocks ; i++ ) { buf = (uint32_t *) dma_priv->blocks[i].data; bufsize = dma_priv->blocks[i].size; nwords = dma_priv->blocks[i].size/nbytes_word; dev_info(dev,"block[%d],size %d: ",i,bufsize); for ( j = 0 ; j < nwords; j++, p++) { dev_info(dev,"DMA: 0x%x, RAM: 0x%x",buf[j],ioread32(p)); } } iounmap(ramb.map); } static int dma_sg_exit(struct test_platform_device * tdev) { struct dma_private_info * dma_priv = _get_dmapip(tdev); int ret = 0; int i; for( i = 0 ; i < dma_priv->nblocks ; i++ ) { kfree(dma_priv->blocks[i].data); } kfree(dma_priv->blocks); sg_free_table(&(dma_priv->sgt)); return ret; } int dma_stop(struct test_platform_device * tdev) { struct dma_private_info * dma_priv = _get_dmapip(tdev); struct device * dev = _get_devp(tdev); int ret = 0; dma_unmap_sg(dev,dma_priv->sgt.sgl,\ dma_priv->sgt.nents, DMA_FROM_DEVICE); dma_sg_exit(tdev); dma_priv->dma_started = 0; return ret; } static void dma_callback(void * param) { enum dma_status dma_stat; struct test_platform_device * tdev = (struct test_platform_device *) param; struct dma_private_info * dma_priv = _get_dmapip(tdev); struct device * dev = _get_devp(tdev); dev_info(dev,"Checking the DMA state....\n"); dma_stat = dma_async_is_tx_complete(dma_priv->dma_chan,\ dma_priv->cookie, NULL, NULL); if(dma_stat == DMA_COMPLETE) { dev_info(dev,"DMA complete! \n"); dma_sg_check(tdev); dma_stop(tdev); } else if (unlikely(dma_stat == DMA_ERROR)) { dev_info(dev,"DMA error! \n"); dma_stop(tdev); } } static void dma_busy_loop(struct test_platform_device * tdev) { struct dma_private_info * dma_priv = _get_dmapip(tdev); struct device * dev = _get_devp(tdev); enum dma_status status; int status_change = -1; do { status = dma_async_is_tx_complete(dma_priv->dma_chan, dma_priv->cookie, NULL, NULL); switch(status) { case DMA_COMPLETE: if(status_change != 0) dev_info(dev,"DMA status: COMPLETE\n"); status_change = 0; break; case DMA_PAUSED: if (status_change != 1) dev_info(dev,"DMA status: PAUSED\n"); status_change = 1; break; case DMA_IN_PROGRESS: if(status_change != 2) dev_info(dev,"DMA status: IN PROGRESS\n"); status_change = 2; break; case DMA_ERROR: if (status_change != 3) dev_info(dev,"DMA status: ERROR\n"); status_change = 3; break; default: dev_info(dev,"DMA status: UNKNOWN\n"); status_change = -1; break; } } while(status != DMA_COMPLETE); dev_info(dev,"DMA transaction completed! \n"); } static int dma_sg_init(struct test_platform_device * tdev) { struct dma_private_info * dma_priv = _get_dmapip(tdev); struct scatterlist *sg; int ret = 0; int i; ret = sg_alloc_table(&(dma_priv->sgt), SG_ENTRIES, GFP_ATOMIC); if(ret) goto out_mem2; dma_priv->nblocks = SG_ENTRIES; dma_priv->blocks = (struct dma_block *) kmalloc(dma_priv->nblocks\ *sizeof(struct dma_block), GFP_ATOMIC); if(dma_priv->blocks == NULL) goto out_mem1; for( i = 0 ; i < dma_priv->nblocks ; i++ ) { dma_priv->blocks[i].size = BUF_SIZE; dma_priv->blocks[i].data = kmalloc(dma_priv->blocks[i].size, GFP_ATOMIC); if(dma_priv->blocks[i].data == NULL) goto out_mem3; } for_each_sg(dma_priv->sgt.sgl, sg, dma_priv->sgt.nents, i) sg_set_buf(sg,dma_priv->blocks[i].data,dma_priv->blocks[i].size); return ret; out_mem3: i--; while(i >= 0) kfree(dma_priv->blocks[i].data); kfree(dma_priv->blocks); out_mem2: sg_free_table(&(dma_priv->sgt)); out_mem1: ret = -ENOMEM; return ret; } static int _dma_start(struct test_platform_device * tdev,int block) { struct dma_private_info * dma_priv = _get_dmapip(tdev); struct device * dev = _get_devp(tdev); int ret = 0; int sglen; /* Step 1: Allocate and initialize the SG list */ dma_sg_init(tdev); /* Step 2: Map the SG list */ sglen = dma_map_sg(dev,dma_priv->sgt.sgl,\ dma_priv->sgt.nents, DMA_FROM_DEVICE); if(! sglen) goto out2; /* Step 3: Configure the DMA */ (dma_priv->dma_config).direction = DMA_DEV_TO_MEM; (dma_priv->dma_config).src_addr_width = DMA_SLAVE_BUSWIDTH_4_BYTES; (dma_priv->dma_config).src_maxburst = 1; (dma_priv->dma_config).src_addr = (dma_addr_t) DEV_BUF; dmaengine_slave_config(dma_priv->dma_chan, \ &(dma_priv->dma_config)); /* Step 4: Prepare the SG descriptor */ dma_priv->dma_desc = dmaengine_prep_slave_sg(dma_priv->dma_chan, \ dma_priv->sgt.sgl, dma_priv->sgt.nents, DMA_DEV_TO_MEM, \ DMA_PREP_INTERRUPT | DMA_CTRL_ACK); if (dma_priv->dma_desc == NULL) { dev_err(dev,"DMA could not assign a descriptor! \n"); goto out1; } /* Step 5: Set the callback method */ (dma_priv->dma_desc)->callback = dma_callback; (dma_priv->dma_desc)->callback_param = (void *) tdev; /* Step 6: Put the DMA descriptor in the queue */ dma_priv->cookie = dmaengine_submit(dma_priv->dma_desc); /* Step 7: Fires the DMA transaction */ dma_async_issue_pending(dma_priv->dma_chan); dma_priv->dma_started = 1; if(block) dma_busy_loop(tdev); return ret; out1: dma_stop(tdev); out2: ret = -1; return ret; } int dma_start(struct test_platform_device * tdev) { return _dma_start(tdev,0); } int dma_start_block(struct test_platform_device * tdev) { return _dma_start(tdev,1); } int dma_init(struct test_platform_device * tdev) { int ret = 0; struct dma_private_info * dma_priv = _get_dmapip(tdev); struct device * dev = _get_devp(tdev); dma_priv->dma_chan = dma_request_slave_channel(dev, \ "dma_chan0"); if (dma_priv->dma_chan == NULL) { dev_err(dev,"DMA channel busy! \n"); ret = -1; } dma_priv->dma_started = 0; return ret; } int dma_exit(struct test_platform_device * tdev) { int ret = 0; struct dma_private_info * dma_priv = _get_dmapip(tdev); if(dma_priv->dma_started) { dmaengine_terminate_all(dma_priv->dma_chan); dma_stop(tdev); dma_priv->dma_started = 0; } if(dma_priv->dma_chan != NULL) dma_release_channel(dma_priv->dma_chan); return ret; }
In my driver source file (
test_driver.c
):#include <linux/kernel.h> #include <linux/module.h> #include <linux/init.h> #include <linux/version.h> #include <linux/device.h> #include <linux/platform_device.h> #include <linux/of_device.h> #include <linux/of_address.h> #include <linux/of_irq.h> #include <linux/interrupt.h> #include "test_driver.h" static int dma_block=0; module_param_named(dma_block, dma_block, int, 0444); static struct test_platform_device tdev; static struct of_device_id test_of_match[] = { { .compatible = "custom,test-driver-1.0", }, {} }; static int test_probe(struct platform_device *op) { int ret = 0; struct device * dev = &(op->dev); const struct of_device_id *match = of_match_device(test_of_match, &op->dev); if (!match) return -EINVAL; tdev.pdev = op; dma_init(&tdev); if(dma_block) ret = dma_start_block(&tdev); else ret = dma_start(&tdev); if(ret) { dev_err(dev,"Error to start DMA transaction! \n"); } else { dev_info(dev,"DMA OK! \n"); } return ret; } static int test_remove(struct platform_device *op) { dma_exit(&tdev); return 0; } static struct platform_driver test_platform_driver = { .probe = test_probe, .remove = test_remove, .driver = { .name = "test-driver", .owner = THIS_MODULE, .of_match_table = test_of_match, }, }; static int test_init(void) { platform_driver_register(&test_platform_driver); return 0; } static void test_exit(void) { platform_driver_unregister(&test_platform_driver); } module_init(test_init); module_exit(test_exit); MODULE_AUTHOR("klyone"); MODULE_DESCRIPTION("DMA SG test module"); MODULE_LICENSE("GPL");
However, the DMA never calls my callback function and I do not have any idea why it happens. Maybe, I am misunderstanding something...
Could anyone help me?
Thanks in advance.
原文:https://stackoverflow.com/questions/37119332
最满意答案
您缺少paddle2的块。
//Paddle collison for top and down "still fixing" if (y + dy < ballRadius || y + dy < 0) { if (x > paddle2X && x < paddle2X + paddleWidth) { dy = -dy; } else { alert("GAME OVER"); document.location.reload(); } } else if (y + dy > canvas.height - ballRadius) { if (x > paddleX && x < paddleX + paddleWidth) { dy = -dy; } else { alert("GAME OVER"); document.location.reload(); } }
You are missing a block for paddle2.
//Paddle collison for top and down "still fixing" if (y + dy < ballRadius || y + dy < 0) { if (x > paddle2X && x < paddle2X + paddleWidth) { dy = -dy; } else { alert("GAME OVER"); document.location.reload(); } } else if (y + dy > canvas.height - ballRadius) { if (x > paddleX && x < paddleX + paddleWidth) { dy = -dy; } else { alert("GAME OVER"); document.location.reload(); } }
相关问答
更多-
确保在将它们分配为新位置时添加'px'。 您正在计算中添加它们。 哪些混乱比较。 即: ballBorderLeft < 0变成'-10px' < 0而不是-10 < 0将字符串与数字值进行比较。 var ball = document.getElementById('ball'); var field = document.getElementById('field'); function getClick() { var fieldCoords = this.getBoundingCl ...
-
Java抓球游戏(Java catch the ball Game)[2022-04-25]
第一个问题:“我不知道我是如何让球以随机宽度出现的。” 我假设你想给球(= comet类的一个实例)一个随机的x位置(= plaats字段)? 您可以进行以下更改(这使得randomNum字段不再需要,现在可以是本地变量): //plaats = randomNum; plaats = randInt(0, 1200); // more code... //public static void randInt(int min, int max) { public static i ... -
在您的代码中,您有: firstClickedObject = getElementAt(clickedX, clickedY); ballClicked(); ballClicked()返回一个布尔值,所以基本上它返回true或false ,并且你没有处理返回值。 你可能意味着做一些事情: firstClickedObject = getElementAt(clickedX, clickedY); if(ballClicked() && !gameStarted){ //Start Game S ...
-
Java编程,突破游戏球物理不符合预期(Java programming, breakout game ball physics not behaving as expected)[2022-11-23]
在碰到球拍时反转球的方向的部分周围添加一个if(dy<0) (假设负dy意味着球朝向球拍)。 这消除了您的方向被更改的可能性,但每次碰撞不止一次 Add an if(dy<0) around the part that reverses direction of the ball when it hits the paddle (assuming a negative dy means the ball is heading towards the paddle). This removes the pos ... -
@Immueggpain这是在按下UP_KEY时向上移动球(2d)的代码。 #include
// GLUT, include glu.h and gl.h #include // Needed for sin, cos #define PI 3.14159265f // Global variables char title[] = "Full-Screen & Windowed Mode"; // Windowed mode's title int ... -
问题是球的self.y和宽度很少“平等”。 因此,您应该检查球是否超出屏幕范围。 您应该将更新方法设置为: [注意] dx和dy变量应该是类的变量而不是从外部传入 def update_ball(self, dx, dy, screen_w, screen_h): #added screen width and height parameters self.x += self.dx self.y += self.dy if self.y > screen_h: se ...
-
您缺少paddle2的块。 //Paddle collison for top and down "still fixing" if (y + dy < ballRadius || y + dy < 0) { if (x > paddle2X && x < paddle2X + paddleWidth) { dy = -dy; } else { alert("GAME OVER"); document.location.reload(); } } else if (y + ...
-
你正在改变它的位置来移动你的盒子。 但是碰撞解决的一个重要部分是速度。 而你的盒子的速度总是为零(从box2d外观点)。 因此,您会遇到奇怪的碰撞解决 You are moving your box by changing its position. But an important part of collision resolution is velocity. And your box's velocity is always zero (from box2d look point). Thus yo ...
-
计算弹跳球的度数(Calculating degrees for bouncing ball)[2024-01-08]
要回答有关角度和反射的问题: 确定您的角度测量系统。 你告诉我一个向上移动的球是180°的角度,所以我猜0°指向下方,角度以逆时针方向增加(向右90° )等。 保持一致非常重要。 设d是该系统中球的运动角度。 定义边框法线向量的角度。 如果顶部的边界是水平的,则其法向量垂直于它并且具有0°的角度(在点1中定义的测量系统中)。 设n就是那个角度。 垂直边界的n = 90° 。 球的出射角度o由下式给出: o = 2*n - d - 180° 请注意,您可能必须对此角度进行标准化,即向/向o加/减360°直到0 ... -
PongGame()。stop_serve(vel =(0,0)) 这是使用不同的球创建一个新的 PongGame实例的python语法,因此stop_serve运行正常但不会影响您实际显示的任何小部件。 您需要使用对现有PongGame的引用。 在这种情况下,您可以使用self.parent.stop_serve() 。 PongGame().stop_serve(vel = (0,0)) This is the python syntax to make a new PongGame instance ...