I'm trying to make a simple platformer using action script 2.0 but I have a problem with getting input from keyboard. I have two function "myKeyDown" and "myKeyUp" that get called whenever a key is pressed down/released.
keyListener.onKeyDown = function(){
myKeyDown();
}
keyListener.onKeyUp = function(){
myKeyUp();
}
The functions check which key was pressed by using Key.getCode() method. It works for myKeyDown but it's buggy for myKeyUp. The bug happens if (for example) I first press A (to move left), then W (to jump), then release W and then release A. The player won't stop moving (even though that's what should happen when you release A)
I understand the problem here. Key.getcode return the code of the last pressed key and what I want is the code for the last released key. I've been searching for hours for a function like this but I haven't found anything.
Here's the code for both myKeyDown and myKeyUp functions
function myKeyDown(){
//A
if(Key.getCode() == 65){
velX=-3;
}else
//D
if(Key.getCode() == 68){
velX=3;
}else
//W
if(Key.getCode() == 87){
if(isInAir == false){
jump();
}
}
}
function myKeyUp(){
//A
if(Key.getCode() == 65){
if(velX==-3){
velX=0;
}
}else
//D
if(Key.getCode() == 68){
if(velX==3){
velX=0;
}
}
}
for cases like this, when you need to hold/release multiple keys a little bit different approach would be better for key handling.
what you can do is use onEnterFrame event listener to check for the pressed keys in case of events when something has to be continuous.
an example
var my_keys:Array = new Array();
my_keys["jump"]=false;
my_keys["right"]=false;
my_keys["left"]=false;
//keydown sets the variables to true
keyListener.onKeyDown = function(){
code=Key.getCode();
if(code==65){
my_keys["left"]=true;
}
if(code==68){
my_keys["right"]=true;
}
if(code==87){
my_keys["jump"]=true;
}
//etc, etc, anything else you wish
//of course, this doesn't prevent you from calling additional one-time events from the keydown!
}
//keyup unsets the button variables
keyListener.onKeyUp = function(){
code=Key.getCode();
if(code==65){
my_keys["left"]=false;
}
if(code==68){
my_keys["right"]=false;
}
if(code==87){
my_keys["jump"]=false;
}
}
now at every point of your game you have a set of keys that are pressed stored in the my_keys array. of course you could use a more generic function inside the keyDown/keyUp and pass the Key.getCode itself directly into the array as indexes instead of the captioned array (like my_keys[Key.getCode()]=true;), it would be even shorter to write. however, i found this to be more illustrative as an example, feel free to modify the code as you need
what you want now is a function that would handle the behavior based on what keys are pressed.
in your case this could, for example, be:
this.onEnterFrame=function(){ //you don't have to use "this" movieclip reference if you have other enterframe events in the movieclip. just don't forget to modify the objcet paths
if(my_keys["left"]){
velX=-3;
}
if(my_keys["right"]){
velX=+3;
}
if((my_keys["jump"])&&(!isInAir)){ //note that i added !isInAir instead of (isInAir==false). this is an equivalent expression, it's just shorter and nicer
jump();
}
}
Related
I am not getting an efficient way to check below mentioned condition.
What I want to achieve is that-
There are some processes that need to be done if their corresponding boolean is true suggesting to start the process. So I want to check if a particular condition is done only if it should be started.
There are some boolean variables
var shouldStartProcessA
var shouldStartProcessB
var shouldStartProcessC
var isADone
var isBDone
var isCDone
if (shouldStartProcessA && shouldStartProcessB && shouldStartC) {
if (isADone && isBDone && isCDone) {
// Every process completed
}
}
if (shouldStartProcessA && shouldStartProcessB) {
if (isADone && isBDone) {
// Every process completed
}
}
if (shouldStartProcessA && shouldStartC) {
if (isADone && isCDone) {
// Every process completed
}
}
if (shouldStartProcessB && shouldStartC) {
if (isBDone && isCDone) {
// Every process completed
}
}
if (shouldStartProcessA) {
if (isADone) {
// Every process completed
}
}
if (shouldStartProcessB) {
if (isBDone) {
// Every process completed
}
}
if (shouldStartProcessC) {
if (isCDone) {
// Every process completed
}
}
This type of validating condition grows exponentially by introducing every other boolean. I am struggling to find a straightforward implementation to check these conditions.
Instead of doing things this way, I'd recommend a data structure that allows you to add tasks and check their state. There are a lot of ways to do that, but the basic idea is you can iterate over all the items and use functions like all to confirm they're all in the appropriate state. That way you don't have to hand-wire everything together
You could use a Map and add tasks to it, initially mapping them to false and setting that to true when they're completed. Or create a Set and add your tasks to that (I'm assuming you want one of each at most), and remove them / move them to a "done" list when they complete. That kind of idea. You could create an enum class to represent your tasks if you want, so each one is its own instance (e.g. Process.A, like having a dedicated, fixed variable) and you can easily use those in your logic
If you really want variables for each process, instead of a data structure, I'd still recommend rolling each pair into a single state, something like this:
enum class State {
UNUSED, PENDING, DONE
}
var processA = State.UNUSED
var processB = State.PENDING
// etc
// you can easily check them like this:
// create a list of all the variables you want to check - we're using references
// to the properties themselves (with the ::), not the current value!
val allProcesses = listOf(::processA, ::processB)
// now you have that collection, you can easily iterate over them all
// and work out what's what - we need to use get() to get the current values
val allFinished = allProcesses
.filterNot { it.get() == State.UNUSED } // ignore unused processes
.all { it.get() == State.DONE } // check ALL the required ones are DONE
You could write that check there as a single all condition, but the point is to show you you can be flexible with it, and build up your logic by filtering out the stuff you're not interested in, if you create a useful set of states
If you really do want to (or have to) stick with the current "pairs of variables" setup, you can do something similar:
// wiring them up again, creating a list of Pairs so we can iterate over them easily
val allProcesses = listOf(
::shouldStartProcessA to ::isADone,
::shouldStartProcessB to ::isBDone,
::shouldStartProcessC to ::isCDone
)
// gotta check 'em all - only returns true if that ALL meet the condition
val allComplete = allProcesses.all { (shouldStart, isDone) ->
// the get() syntax is awkward, but basically for everything we're checking
// if it either doesn't need to start, or it does but it's also done
!shouldStart.get() || (shouldStart.get() && isDone.get())
}
so adding new processes is just a case of adding their variables to the list of pairs, and they get included in the checking
You don't need the property reference stuff (::/.get()) if you create the lists right before you check them, but if you want to define them once in advance (and the property values can change after that) then that's how you'd do it. Otherwise you can just do the normal shouldStartProcessA to isADone etc, which is probably fine for most cases - I'm showing the reference stuff as a more general example for handling this kind of thing
I suppose, you should create two lists of Boolean and add variables consequently.
val list1 = listOf(shouldStartProcessA, shouldStartProcessB, shouldStartC)
val list2 = listOf(isADone, isBDone, isCDone)
Then iterate over both lists and check that items in corresponding positions have the same values.
var n = 0
for (i in list1.indices) {
if (list1[i] == list2[i]) {
n++
} else {
n = 0
break
}
}
if (n > 0) {
// Every process completed
}
I thought it's easy. Like always
//somewhere inside constructor
overlay.addOnTouchListener(this)
//...
override fun onTouch(v: View?, event: MotionEvent?): Boolean {
event?:return false
if (event.actionMasked == MotionEvent.ACTION_DOWN || event.actionMasked == MotionEvent.ACTION_POINTER_DOWN) {
//start drag
moving=true
} else if (event.actionMasked == MotionEvent.ACTION_MOVE) {
if (!moving) return true
//do drag
} else if (event.actionMasked == MotionEvent.ACTION_UP) {
//stop drag
println("touch:up(${event.pointerCount})")
}
return true
}
I was expecting MotionEvent.ACTION_UP will fire up on release of each finger.But looks like it only fires once for the last finger.
Is there way catch moment when user releases one finger but keep's moving another one?
You can use two methods getPointerCount(x) and/or getPointerId(x).
getPointerCount gets the number of pointers of data contained in an event. This is always >= 1.
While getPointerId() returns the pointer identifier associated with a particular pointer data index in an event. The identifier tells you the actual pointer number associated with the data, accounting for individual pointers going up and down since the start of the current gesture.
So in your case, if you want to capture the pointer that was not removed from the screen, you can use getPointerCount to check if there has been a pointer removed and then use getPointerId to assign some sort of function when the last pointer has been released.
The initial statement is incorrect. Actualy android notifies all touch ups with events MotionEvent.ACTION_UP/MotionEvent.ACTION_POINTER_UP
how would it be possible to bypass functions that are not existing in DM
such that the main code would still run? Try/catch does not seem to work, e..g
image doSomething(number a,number b)
{
try
{
whateverfunction(a,b)
}
catch
{
continue
}
}
number a,b
doSomething(a,b)
Also conditioning wont work, e.g..
image doSomething(number a,number b)
{
if(doesfunctionexist("whateverfunction"))
{
whateverfunction(a,b)
}
}
number a,b
doSomething(a,b)
thanks in advance!
As "unknown" commands are caught by the script-interpreter, there is no easy way to do this. However, you can construct a workaround by using ExecuteScriptCommand().
There is an example tutorial to be found in this e-book, but in short, you want to do something like the following:
String scriptCallStr = "beep();\n"
scriptCallStr = "MyUnsaveFunctionCall();\n"
number exitVal
Try { exitVal = ExecuteScriptString(scriptCallStr ); }
Catch { exitVal = -1; break; }
if ( -1 == exitVal )
{
OKDialog("Sorry, couldn't do:\n" + scriptCallStr )
}
else
{
OKDialog( "All worked. Exit value: " + exitVal )
}
This works nicely and easy for simple commands and if your task is only to "verify" that a script could run.
It becomes clumsy, when you need to pass around parameters. But even then there are ways to do so. (The 'outer' script could create an object and pass the object-ID per string. Similarly, the 'inner' script can do the same and return the script-object ID as exit-value.)
Note: You can of course also put doesfunctionexist inside the test-script, if you do only want to have a "safe test", but don't actually want to execute the command.
Depending on what you need there might also be another workaround solution: Wrapper-functions in a library. This can be useful if you want to run the same script on different PCs with some of which having the functionality - most likely some microscope - while others don't.
You can make your main-script use wrapper methods and then you install different versions of the wrapper method script scripts as libraries.
void My_SpecialFunction( )
{
SpecialFunction() // use this line on PCs which have the SpecialFunction()
DoNothing() // use alternative line on PCs which don't have the SpecialFunction()
}
My_SpecialFunction( )
I have used this in the past where the same functionality (-stage movement-) required different commands on different machines.
Within qt's item/view framework, I'm trying to save a QColorDialog as user data and then retrieve that dialog as the editor, as well as during paint, in a tableview.
In my class constructor I do
QStandardItem *item = new QStandardItem();
QColorDialog *colorDlg = new QColorDialog(QColor(0,0,255), this);
item->setData(QVariant::fromValue(colorDlg), ColorDialogRole);
mTableModel->setItem(0,2,item);
then, inside my delegate's paint function I have
void ReportFigureTableDelegate::paint(QPainter *painter, const QStyleOptionViewItem &option, const QModelIndex &index) const
{
QVariant vColorDlg= index.data(ReportFigure::ColorDialogRole);
if(vColorDlg.isValid())
{
////////////////////////////////////////////////
// Program segfaults on the next line ... why?
////////////////////////////////////////////////
QColorDialog *colorDlg = qvariant_cast<QColorDialog*>(vColorDlg);
if(colorDlg != NULL)
{
painter->save();
QStyleOptionViewItem opt = option;
initStyleOption(&opt, index);
painter->fillRect(opt.rect, colorDlg->selectedColor());
painter->restore();
}
else
QStyledItemDelegate::paint(painter, option, index);
}
else
QStyledItemDelegate::paint(painter, option, index);
}
During runtime, the table shows up the first time (although with the wrong color ... different issue I assume). I double click to edit the cell and it brings up the dialog as expected. When I close, though, it segfaults on the indicated line. I don't understand why since I think I'm doing all the necessary checks.
You set the data on a QStandardItem object. Meanwhile you are retrieving the data on a QModelIndex object. Now why is the variant valid is a mystery. Maybe because ReportFigure::ColorDialogRole is equal to a build-in Qt role while it should be at least Qt::UserRole.
Anyway In the paint() method you can access the previously set item using
QStandardItem *item = mTableModel->itemFromIndex(index);
I have a method whose purpose is to retrieve collection items.
A collection can contain a mix of items, let's say: pens, pencils, and papers.
The 1st parameter allows me to tell the method to retrieve only the itemTypes I pass (e.g, just pens and pencils).
The 2nd parameter flags the function to use the collection's default item types, instead.
getCollectionItems($itemTypes,$useCollectionDefaultItemTypes) {
foreach() {
foreach() {
foreach() {
// lots of code...
if($useCollectionDefaultItemTypes) {
// get collection's items using collection->itemTypes
}
else {
// get collection's items using $itemTypes
}
// lots of code...
}
}
}
}
What feels odd is that if I set the $useCollectionDefaultItemTypes to true, there is no need for the function to use the first parameter. I was considering refactoring this method into two such as:
getCollectionItems($itemTypes); // get the items using $itemTypes
getCollectionItems(); // get the items using default settings
The problem is that the methods will have lots of duplicate code except for the if-statement area.
Is there a better way to optimize this?
Pass in $itemTypes as null when you're not using it. Have your if statement check if $itemTypes === null; if it is, use default settings.
If this is php, which I assume it is, you can make your method signature function getCollectionItems($itemTypes = null) and then you can call getCollectionItems() and it will call it as if you had typed getCollectionItems(null).
It's generally a bad idea to write methods that use flags like that. I've seen that written in several places (here at #16, Uncle Bob here and elsewhere). It makes the method hard to understand, read, and refactor.
An alternative design would be to use closures. Your code could look something like this:
$specificWayOfProcessing = function($a) {
//do something with each $a
};
getCollectionItems($processer) {
foreach() {
foreach() {
foreach() {
// lots of code...
$processor(...)
// lots of code...
}
}
}
}
getCollectionItems($specificWayOfProcessing);
This design is better because
It's more flexible. What happens when you need to decide between three different things?
You can now test the code inside the loop much easier
It is now easier to read, because the last line tells you that you are "getting collection items using a specific way of processing" - it reads like an English sentence.
Yes, there is a better way of doing this -- though this question is not an optimization question, but a style question. (Duplicated code has little effect on performance!)
The simplest way to implement this along the lines of your original idea is to make the no-argument form of getCollectionItems() define the default arguments, and then call the version of it that requires an argument:
getCollectionItems($itemTypes) {
foreach() {
foreach() {
foreach() {
// lots of code...
// get collection's items using $itemTypes
}
// lots of code...
}
}
}
getCollectionItems() {
getCollectionItems(collection->itemTypes)
}
Depending on what language you are using, you may even be able to collapse these into a single function definition with a default argument:
getCollectionItems($itemTypes = collection->itemTypes) {
foreach() {
foreach() {
foreach() {
// lots of code...
// get collection's items using $itemTypes
}
// lots of code...
}
}
}
That has the advantage of clearly expressing your original idea, which is that you use $itemTypes if provided, and collection->itemTypes if not.
(This does, of course, assume that you're talking about a single "collection", rather than having one of those foreach iterations be iterating over collections. If you are, the idea to use a null value is a good one.)