Click here to Skip to main content
15,868,016 members
Articles / Desktop Programming / Windows Forms

Fishy Fishy Fish

Rate me:
Please Sign up or sign in to vote.
4.90/5 (40 votes)
2 Apr 2010CPOL3 min read 92.2K   5.8K   86   29
Just for fun; a bunch of fish swimming around the screen

Introduction

This article is a bit of a homage to Davidwu's excellent article, A lovely goldfish desktop pet. In that article, David demonstrates using alpha-blending and GDI+ to make a little fish swim across the screen.

I've taken that code and extended it to support multiple fish along with a SysTray icon to control the number of fish in your tank.

FishTank/screenshot2.png

I also added some different colored fish images for a little variety.

FishTank/screenshot.jpg

Using the Code

The code is largely the same as the original, though I've moved things around a bit in order to support multiple fish. Unlike the original code, frames are extracted from the source PNG at startup rather than at each timer tick.

C#
class Frameset : List<Bitmap>, IDisposable
{
    public Frameset(Bitmap b, int framecount)
    {
        if (!Bitmap.IsCanonicalPixelFormat(b.PixelFormat) || 
              !Bitmap.IsAlphaPixelFormat(b.PixelFormat))
            throw new ApplicationException("The picture must be 32bit
                  picture with alpha channel.");

        FrameWidth = b.Width / framecount;
        FrameHeight = b.Height;

        for (int i = 0; i < framecount; i++)
        {
            Bitmap bitmap = new Bitmap(FrameWidth, FrameHeight);
            using (Graphics g = Graphics.FromImage(bitmap))
                g.DrawImage(b, new Rectangle(0, 0, FrameWidth, FrameHeight),
                   new Rectangle(FrameWidth * i, 0, FrameWidth, FrameHeight), 
                   GraphicsUnit.Pixel);

            Add(bitmap);
        }
    }

    public int FrameWidth { get; private set; }

    public int FrameHeight { get; private set; }

    public void Dispose()
    {
        foreach (Bitmap f in this)
            f.Dispose();

        Clear();
    }
}

This greatly reduces the CPU usage for the animation which is important with a whole tankful swimming around. There is also a Form derived from the main FishForm to host the NotifyIcon in the system tray. An instance of this form will always be the first one created. The NotifyIcon context menu allows the user to add and remove fish, show and hide all the fish and of course exit the application.

.NET 4

The project files are all in VS.NET 2010 format, but the only .NET 4 type used is the Tuple. Sacha posted a version of a Tuple in the comments below. So if you want to play with this in 2008 and .NET 3.5, you'll need to incorporate that snippet or otherwise replace the Tuple usage, which shouldn't be too hard.

Conversion to UWP

With the Windows 10 Anniversary release and the introduciton of the Desktop App Converter, I decided to see if this would run as a UWP app. The whole conversion process was remarkably simple.

1) The first step was to update the project from vs.net 2010 to 2015 (specifically the 15 Release 3 Preview - more on that later) and then target .NET 4.6.1. No issues there.

2) Next a UWP AppXManifext layout file needed to be created. I decided to go the manual route since this thing is xcopy deployable. The manifest is about as simple as can be. Really the hardest part was refreshing myself on app signing. In the end I added a couple build event scripts that rebuild the appx package with each build. Drop that and some logo png's into the solution folder.

AppXManifest.xml
<?xml version="1.0" encoding="utf-8"?>
<Package
   xmlns="http://schemas.microsoft.com/appx/manifest/foundation/windows10"
   xmlns:uap="http://schemas.microsoft.com/appx/manifest/uap/windows10"
   xmlns:rescap="http://schemas.microsoft.com/appx/manifest/foundation/windows10/restrictedcapabilities">
  <Identity Name="[this is the guid of your package]"
    ProcessorArchitecture="x86"
    Publisher="CN=kackman.net"
    Version="1.1.11.0" />
  <Properties>   
    <DisplayName>Fishy Fishy Fish</DisplayName>
    <PublisherDisplayName>Reserved</PublisherDisplayName>
    <Description>Some fish. Swimming around on your screen.</Description>
    <Logo>StoreLogo.png</Logo>
  </Properties>
  <Resources>
    <Resource Language="en-us" />
  </Resources>
  <Dependencies>
    <TargetDeviceFamily Name="Windows.Desktop" MinVersion="10.0.14316.0" MaxVersionTested="10.0.14393.0" />
  </Dependencies>
  <Capabilities>
    <rescap:Capability Name="runFullTrust"/>   
  </Capabilities>
  <Applications>
    <Application Id="FishyFishyFish" Executable="FishyFish.exe" EntryPoint="Windows.FullTrustApplication">     
      <uap:VisualElements
         BackgroundColor="transparent"
         DisplayName="Fishy Fishy Fish"
         Square150x150Logo="Square150x150Logo.png"
         Square44x44Logo="Square44x44Logo.png"
         Description="Some fish. Swimming around on your screen." />      
    </Application>
  </Applications>
</Package>
Prebuild
:: clean any previous AppX outputs
rmdir AppX /s /q
del $(TargetName).appx /q /f
Postbuild
:: copy all of the files that go into the AppX into a working folder
mkdir AppX
xcopy "$(TargetPath)" AppX\ /R /Y
xcopy "$(TargetPath).config" AppX\ /R /Y
xcopy "$(SolutionDir)appxmanifest.xml" AppX\ /R /Y
xcopy "$(SolutionDir)StoreLogo.png" AppX\ /R /Y
xcopy "$(SolutionDir)Square44x44Logo.png" AppX\ /R /Y
xcopy "$(SolutionDir)Square150x150Logo.png" AppX\ /R /Y

:: build a new AppX package
"$(Win10SDKDir)MakeAppX.exe" pack /d AppX /p $(TargetName).appx
"$(Win10SDKDir)SignTool.exe" sign -f d:\temp\tempca.pfx -fd SHA256 -v .\$(TargetName).appx
(note $(Win10SDKDir) is a variable added to the csproj file that points to the windows 10 sdk folder.)
<PropertyGroup>
  <Win10SDKDir Condition=" '$(Win10SDKDir)' == '' ">C:\Program Files (x86)\Windows Kits\10\bin\x64\</Win10SDKDir>
</PropertyGroup>
 
3) Then the installation of a vs.net add-in that allows you to debug the AppX. This is where you need Visual Studio 15 Preview (which is different than Visual Studio 2015 confusingly enough) becuase the that extension only works with the Preview VS at the time of this writing. With that installed the bedugger attaches to the AppX as if your project were a normal UWP app and away you go.
 
That was about all there was to it. All in all the documentation on the app converter is very helpful, with plenty of step by step instructions that you wouldn't be able to figure out on your own. I highly recommend going through it before embarking on a conversion.

Conclusion

Oh, and I kind of cheated on the fish colorizing. I color shifted the source PNG in Paint.Net and saved each one as a new set of images. That's why the project size is large. Perhaps someday I'll correct that short cut but for now my apologies for the extra large download. :)

That's about all there is to it. It's been a fun little project to play around with (and the family and friends I've given it to have enjoyed it as well). This will probably be my last WinForms article. I've caught the WPF bug and am finally cresting the learning curve.

History

  • 3/31/2010 - Initial post
  • 8/3/2016 - UWP section

License

This article, along with any associated source code and files, is licensed under The Code Project Open License (CPOL)


Written By
Team Leader Starkey Laboratories
United States United States
The first computer program I ever wrote was in BASIC on a TRS-80 Model I and it looked something like:
10 PRINT "Don is cool"
20 GOTO 10

It only went downhill from there.

Hey look, I've got a blog

Comments and Discussions

 
QuestionCould you help me to create some butterfly animation? Pin
Member 1193807011-Oct-15 6:09
Member 1193807011-Oct-15 6:09 
QuestionFantastic !! 5 of 2 ;) !! Pin
tvks16-Sep-14 10:26
tvks16-Sep-14 10:26 
AnswerRe: Fantastic !! 5 of 2 ;) !! Pin
Don Kackman16-Sep-14 14:55
Don Kackman16-Sep-14 14:55 
QuestionItem1 does not exist Pin
Sivaji156514-Feb-14 23:17
Sivaji156514-Feb-14 23:17 
AnswerRe: Item1 does not exist Pin
Don Kackman16-Feb-14 2:35
Don Kackman16-Feb-14 2:35 
GeneralVery nice article Pin
Sivaji156514-Feb-14 23:07
Sivaji156514-Feb-14 23:07 
I love it.
QuestionThis smells... Pin
Brisingr Aerowing5-Jan-13 3:25
professionalBrisingr Aerowing5-Jan-13 3:25 
AnswerRe: This smells... Pin
Don Kackman16-Jan-13 12:47
Don Kackman16-Jan-13 12:47 
GeneralMy vote of 5 Pin
Peter Hawke20-Dec-11 14:52
Peter Hawke20-Dec-11 14:52 
GeneralMy vote of 5 Pin
Pravin Patil, Mumbai11-Oct-11 22:32
Pravin Patil, Mumbai11-Oct-11 22:32 
GeneralMy vote of 5 Pin
version_2.08-Jun-11 23:29
version_2.08-Jun-11 23:29 
GeneralMy vote of 5 Pin
ARon_23-Mar-11 4:44
ARon_23-Mar-11 4:44 
Generalgood one Pin
Pranay Rana20-Dec-10 1:47
professionalPranay Rana20-Dec-10 1:47 
GeneralMy vote of 5 Pin
skumar0194-Dec-10 1:49
skumar0194-Dec-10 1:49 
GeneralMy vote of 5 Pin
OrganicHuman17-Jul-10 0:26
OrganicHuman17-Jul-10 0:26 
GeneralRe: My vote of 5 Pin
Don Kackman23-Jul-10 4:06
Don Kackman23-Jul-10 4:06 
Questiontuple? Pin
Christ Kennedy1-Apr-10 1:43
mvaChrist Kennedy1-Apr-10 1:43 
AnswerRe: tuple? PinPopular
Sacha Barber1-Apr-10 2:21
Sacha Barber1-Apr-10 2:21 
GeneralRe: tuple? Pin
Don Kackman1-Apr-10 2:34
Don Kackman1-Apr-10 2:34 
AnswerRe: tuple? Pin
Sacha Barber1-Apr-10 2:53
Sacha Barber1-Apr-10 2:53 
GeneralRe: tuple? Pin
Christ Kennedy1-Apr-10 4:26
mvaChrist Kennedy1-Apr-10 4:26 
GeneralRe: tuple? Pin
Sacha Barber1-Apr-10 4:31
Sacha Barber1-Apr-10 4:31 
GeneralThats.. Pin
Gary Noble31-Mar-10 22:38
Gary Noble31-Mar-10 22:38 
GeneralRe: Thats.. Pin
Don Kackman1-Apr-10 6:22
Don Kackman1-Apr-10 6:22 
GeneralLike it, and maybe you will like this one too Pin
Sacha Barber31-Mar-10 21:41
Sacha Barber31-Mar-10 21:41 

General General    News News    Suggestion Suggestion    Question Question    Bug Bug    Answer Answer    Joke Joke    Praise Praise    Rant Rant    Admin Admin   

Use Ctrl+Left/Right to switch messages, Ctrl+Up/Down to switch threads, Ctrl+Shift+Left/Right to switch pages.