I am coding UNO and want to make a method to check if the player can throw a card mathcing that on the table. If not, then method return true and the player can draw extra cards. If a match can be made, then the method returns false and the player can not draw cards.
I have made a label for the card on the table, called discardpileLabel and an JButton arraylist for the players cards. The method isValid() is called when draw button is clicked.
public boolean isValid ()
{
int i = 0;
do
{
if ((discardpileLabel.getName()).charAt(0) == (playersCards2.get(i)).getName()).charAt(0)
||(discardpileLabel.getName()).charAt(1) == ((playersCards2.get(i)).getName()).charAt(1))
{
return false;
} else i++;
} while (i < playersCards2.size());
return true;
}
I want the nullPointerException on the if statement to go away.
If you want to throw Custom Exceptions
Check : Custom Exception C#
Related
My monogame game has stopped responding to mouse clicks. Prior to version 3.5, this was working fine. Here's how I'm currently getting the input:
protected override void Update (GameTime game_time)
{
Mouse_Input (game_time);
}
void Mouse_Input(GameTime game_time)
{
mouse_current = Mouse.GetState();
if (mouse_current.LeftButton == ButtonState.Pressed)
{
// click
}
}
Setting breakpoints in the function reveals all the code is being hit, but LeftButton is always ButtonState.Released.
I've tried with both a wired mouse and the trackpad. Keyboard input is working fine. Anyone else running into this?
I always use this way.
MouseState currentMouseState;
MouseState oldMouseState;
public bool checkClick()
{
oldMouseState = currentMouseState;
currentMouseState = Mouse.GetState();
if (Visible)
{
if (currentMouseState.LeftButton == ButtonState.Pressed && oldMouseState.LeftButton == ButtonState.Released)
{
return true;
}
}
}
If you want to check if the Mouse clicks on a Rectangle (Hud elements for example)
public bool checkClickRectangle(Rectangle rec)
{
oldMouseState = currentMouseState;
currentMouseState = Mouse.GetState();
if (Visible)
{
if (rec.Contains(new Vector2(Mouse.GetState().X, Mouse.GetState().Y)) && currentMouseState.LeftButton == ButtonState.Pressed && oldMouseState.LeftButton == ButtonState.Released)
{
return true;
}
}
}
This was actually a not a problem with Monogame, but a problem in my game logic that was very difficult to track down.
After upgrading to 3.5, I had to reconfigure how my Texture2D's were being loaded, which also meant refactoring some classes. I ended up with a class within a class which were both inheriting from Game.
public class Brush_Control : Game
{
public class Tile : Game
{
Process of elimination narrowed the search to this class. I believe this caused an infinite loop that interfered with the input somehow, but without throwing an error or causing an obvious freeze.
Removing the inner Game reference as a parent fixed the problem, and it turns out I no longer need to have it there anyway.
My purpose is that the users will never be able to check a TCheckBox when the number is entered into a TEdit less than 7 digits. Also, this TCheckBox can never be checked when the TEdit is being empty.
A problem of my codes is sometimes TCheckBox can still be checked although TEdit is being empty.
Moreover, my another target is that the start button can never be executed or will always display an error message if the start button is clicked when the TCheckBox is checked while the TEdit is being empty.
The problem is what codes should I put in the start button ?.
I am using the following code:
//--------------------------------------------------------------------------------
void __fastcall TForm::MyTEditBoxKeyPress(TObject *Sender, System::WideChar &Key)
{
if( Key == VK_BACK ) return;
if((Key < '1') || (Key > '9'))
{
MessageDlg("Please enter number only.",mtInformation, TMsgDlgButtons()<< mbOK, 0);
Key = 0;
}
}
//--------------------------------------------------------------------------------
void __fastcall TForm::MyTEditBoxExit(TObject *Sender)
{
if (MyTEditBox->Text.Length() < 7) {
MessageDlg("Please enter at least 7 digit.",mtInformation, TMsgDlgButtons()<< mbOK, 0);
}
}
//--------------------------------------------------------------------------------
void __fastcall TForm::MyCheckBoxClick(TObject *Sender)
{
if (MyCheckBox->Tag == 0 ) {
MyCheckBox->Tag = 1;
if (MyTEditBox->Text.Length() >= 7)
MyCheckBox->Checked = true;
IdThrottler->BitsPerSec = StrToInt64(MyTEditBox->Text);
}
else {
MyCheckBox->Tag = 0;
if (MessageDlg("Please enter at least 7 digit.",mtInformation, TMsgDlgButtons()<< mbOK, 0) == mrYes)
MyCheckBox->Checked = false;
}
}
First off, the throttler's BitsPerSec property is an int, not an __int64, so you should be using StrtoInt() instead of StrToInt64().
You are setting the TCheckBox::Enabled property in the TCheckBox::OnClick event, so the user has to actually click on the TCheckBox to make it update itself. If the user only typed in the TEdit and never clicks on the TCheckBox, it will never be updated.
If you don't want the user to click on the TCheckBox at all unless the TEdit text is adequate, you should use the TEdit::OnChange event to set the TCheckBox::Enabled property, and get rid of your TCheckBox::Tag handling altogether:
void __fastcall TMyForm::MyTEditBoxChange(TObject *Sender)
{
MyCheckBox->Enabled = (MyTEditBox->GetTextLen() >= 7);
}
void __fastcall TMyForm::MyCheckBoxClick(TObject *Sender)
{
if (MyCheckBox->Checked)
IdThrottler->BitsPerSec = StrToInt(MyTEditBox->Text);
else
IdThrottler->BitsPerSec = 0;
}
Do note that just because the user can type in more than 6 digits does not mean its Text represents a value int value. In that situation, StrToInt() will raise an exception.
A different way to handle this is to add a TActionList to your Form, create a custom action in it, assign that action to the TCheckBox::Action property, and then use the TAction::OnUpdate event to set the TAction::Enabled property (which will enable/disable the TCheckBox):
void __fastcall TMyForm::MyActionUpdate(TObject *Sender)
{
MyAction1->Enabled = (MyTEditBox->GetTextLen() >= 7);
}
The benefit of this approach is that the TCheckBox::Enabled property will be updated automatically and in real-time without having to manually react to changes in the TEdit at all.
With that said, if you are using a modern version of C++Builder, TEdit has a NumbersOnly property. When set to true, you don't have to filter keystrokes in the TEdit::OnKeyPress event anymore, the OS will prevent the user from typing non-digit characters for you (besides, when you are filtering manually, you are not allowing the user to type in 0 digits, which is wrong).
If you really must allow the user to enter a number via a TEdit, and if the TEdit::NumbersOnly property is not available in your version of C++Builder, you still have a couple of other options (which you should consider anyway, even in modern C++Builder versions):
make the TEdit read-only, attach a TUpDown to it via the TUpDown::Associate property, and assign appropriate TUpDown::Min and TUpDown::Max values as needed. Use the TUpDown::Position property to update the throttler's BitsPerSec property:
void __fastcall TMyForm::MyActionUpdate(TObject *Sender)
{
MyAction1->Enabled = (MyUpDown->Position > 999999);
}
void __fastcall TMyForm::MyUpDownClick(TObject *Sender, TUDBtnType Button)
{
if ((MyCheckBox->Enabled) && (MyCheckBox->Checked))
IdThrottler->BitsPerSec = MyUpDown->Position;
else
IdThrottler->BitsPerSec = 0;
}
Maybe also use a TTrackBar that sets the TUpDown::Value property in larger increments so the user does not have to press the up/down arrows for more than small adjustments:
void __fastcall TMyForm::MyTrackBarChange(TObject *Sender)
{
MyUpDown->Position = MyTrackBar->Position;
MyUpDownClick(NULL, btNext);
}
Don't bother using a TEdit at all. Use a TCSpinEdit or TSpinEdit instead (depending on your version of C++Builder). The user can type in numbers, and it will reject non-numeric input. It provides up/down arrows, like TUpDown, for making small adjustments. And it has a Value property that returns/accepts an int instead of a String, just like the TUpDown::Position property.
void __fastcall TMyForm::MyActionUpdate(TObject *Sender)
{
MyAction1->Enabled = (MySpinEdit->Value > 999999);
}
void __fastcall TMyForm::MySpinEditChange(TObject *Sender)
{
if ((MyCheckBox->Enabled) && (MyCheckBox->Checked))
IdThrottler->BitsPerSec = MySpinEdit->Value;
else
IdThrottler->BitsPerSec = 0;
}
Either way, the user cannot enter non-numeric values at all, and the TCheckBox still auto-disables itself for values that are smaller than your desired threshold.
I am having a class inherited from QGraphicsScene. I have a mouseMoveEvent in this class. Based on the mouse move I am sending the co ordinates via signal to the main window. I have multiple GraphicViews in main window. Based on the scene from which the signal is received I am display the scene co ordinates using QGraphicsTextItem.
The problem is when I move out of the scene area I am unable to hide the QGraphicsTextItem.
Can someone give me a work around for this?
Class Scene::QGraphicsScene
{
void MouseMoveEvent(QGraphicsSceneMouseEvent *Event)
{
int XPos = event.x();
int YPos = event.y();
emit SignalPos(XPos,YPos);
}
}
//In Main Window
connect(scene1,SignalPos(int,int),this,SlotPos1(int,int);
//Similarly for scene2,scene3,scene4
void MainWindow::SlotPos(int X, int Y)
{
m_qgtxtItemX.setText(QString::x);
//I want to hide this once I am out of scene.It is a member variable. I tried
//taking local variable but it didn't work.
//Similarly for y and other slots
}
Install an event filter on the scene.
scene1->installEventFilter(this);
then implement the method in the class that is referenced by "this":
bool eventFilter(QObject *watched, QEvent *event) {
if (event->type() == QEvent::Leave)
{
qDebug() << "Mouse left the scene";
}
return false;
}
Just tried it and it worked! If you are installing the event filter on more than one object, please use "watched" to differentiate between them.
Best,
I've been reading various tutorials on how to write a contact listener, and I can't wrap my head around it.
Here is what I have so far:
In each of the classes that I have representing a physics object I do:
_body->SetUserData(self);
I write a contact listener class containing the following two methods:
void ContactListener::BeginContact(b2Contact* contact)
{
// Box2d objects that collided
b2Fixture* fixtureA = contact->GetFixtureA();
b2Fixture* fixtureB = contact->GetFixtureB();
// Sprites that collided
MyNode* actorA = (MyNode*) fixtureA->GetBody()->GetUserData();
MyNode* actorB = (MyNode*) fixtureB->GetBody()->GetUserData();
}
void ContactListener::EndContact(b2Contact* contact)
{
// Box2d objects that collided
b2Fixture* fixtureA = contact->GetFixtureA();
b2Fixture* fixtureB = contact->GetFixtureB();
// Sprites that collided
MyNode* actorA = (MyNode*) fixtureA->GetBody()->GetUserData();
MyNode* actorB = (MyNode*) fixtureB->GetBody()->GetUserData();
}
I don't know what to do next. I now have the two sprites which are colliding, but I want to do the following:
1) When they collide, I want to remove one of the sprites from the world, based on the type of object. (for example if one a cat object and the other is a mouse object, I want to remove the mouse object.
2) I want to let the cat object know it ate a mouse
3) I want the cat to continue moving as if it didn't contact with the mouse.
4) I still wan't the cat to collide normally with things like the terrain.
What do I do next ? I'm pretty clueless on what to do? How do I get the cat to continue to collide normally with the terrain, but not with the mouse? When do I remove the mouse?
Having an "Entity" class that hold the reference to the Box2D body and does the manipulations on it is definitely a good way to go. If you have a Spaceship class vs. a Meteor class, each of them can supply their own derived methods of controlling the body (AI), but each of them has common logic and code to support operations on "Things that have a body" (e.g. common "Entity" base class). I think you are on the right track.
It gets a little murky when the contacts start happening. This is where you start getting into the architecture of your overall system, not just the structure of the physics world or a single Coco2d Scene.
Here is how I have done this in the past:
First I set up the contact listener, listed below:
class EntityContactListener : public ContactListener
{
private:
GameWorld* _gameWorld;
EntityContactListener() {}
typedef struct
{
Entity* entA;
Entity* entB;
} CONTACT_PAIR_T;
vector<CONTACT_PAIR_T> _contactPairs;
public:
virtual ~EntityContactListener() {}
EntityContactListener(GameWorld* gameWorld) :
_gameWorld(gameWorld)
{
_contactPairs.reserve(128);
}
void NotifyCollisions()
{
Message* msg;
MessageManager& mm = GameManager::Instance().GetMessageMgr();
for(uint32 idx = 0; idx < _contactPairs.size(); idx++)
{
Entity* entA = _contactPairs[idx].entA;
Entity* entB = _contactPairs[idx].entB;
//DebugLogCPP("Contact Notification %s<->%s",entA->ToString().c_str(),entB->ToString().c_str());
msg = mm.CreateMessage();
msg->Init(entA->GetID(), entB->GetID(), Message::MESSAGE_COLLISION);
mm.EnqueueMessge(msg, 0);
msg = mm.CreateMessage();
msg->Init(entB->GetID(), entA->GetID(), Message::MESSAGE_COLLISION);
mm.EnqueueMessge(msg, 0);
}
_contactPairs.clear();
}
void PreSolve(b2Contact* contact, const b2Manifold* oldManifold)
{
b2Fixture* fixtureA = contact->GetFixtureA();
b2Body* bodyA = fixtureA->GetBody();
Entity* entityA = bodyA->GetUserData();
b2Fixture* fixtureB = contact->GetFixtureB();
b2Body* bodyB = fixtureB->GetBody();
Entity* entityB = bodyB->GetUserData();
if(test if entityA and entityB should not have collision response)
{
contact->SetEnabled(false);
}
// Do this if you want there to be collision notification, even if
// there is no response.
AddContactPair(entA,entB);
}
void AddContactPair(Entity* entA, Entity* entB)
{
for(uint32 idx = 0; idx < _contactPairs.size(); idx++)
{
if(_contactPairs[idx].entA == entA && _contactPairs[idx].entB == entB)
return;
// Not sure if this is needed...
if(_contactPairs[idx].entA == entB && _contactPairs[idx].entA == entB)
return;
}
CONTACT_PAIR_T pair;
pair.entA = entA;
pair.entB = entB;
_contactPairs.push_back(pair);
}
// BEWARE: You may get multiple calls for the same event.
void BeginContact(b2Contact* contact)
{
Entity* entA = (Entity*)contact->GetFixtureA()->GetBody()->GetUserData();
Entity* entB = (Entity*)contact->GetFixtureB()->GetBody()->GetUserData();
assert(entA != NULL);
assert(entB != NULL);
// Not sure this is still needed if you add it in the pre-solve.
// May not be necessary...
AddContactPair(entA, entB);
}
// BEWARE: You may get multiple calls for the same event.
void EndContact(b2Contact* contact)
{
}
};
Because of the way the engine works, you can get multiple contact hits for the same bodies. This listener filters them so if two Entities collide, you only get one message.
The Listener only stores the collisions that have occurred. It could be modified to further separate them into "begins" and "ends" for other purposes. Here, contact meant "you've been hit by something". I didn't need to know if it stopped contacting.
The call to NotifyCollisions is the "secret sauce". It sends out a message to both the contacted entities (via a message system) that they hit something and the other Entity is what they hit. Bullet hit ship. Bullet destroys self. Ship damages self based on bullet properties (GetDamageInflicted() method). This in turn signals the graphics system to remove the bullet from the display. If the ship was destroyed, it is destroyed as well.
From an overall execution standpoint:
Before you begin, assign the contact listener.
Each Cycle of your game:
Call "Update" on all your Entities. This updates their physics forces, etc.
Update Box2d world.
Call NotifyCollisions on Listener.
Remove dead Entities from system.
Was this helpful?
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();
}
}